عملگرهای اصلی حسابی و مقایسه را میتوان برای استفاده در کلاسها و ساختارهای خودتان سازگار کرد. به این کار سربارگذاری عملگر میگویند.
این مقاله بحثی مفصل دربارهی نحوهی نگارش و همچنین این است که کدام عملگرها را میتوان سربارگذاری کرد و کدامها را نه.
بیشتر عملگرها این شکل را دارند:
static <return type> operaator <operator symbols>(<parameters>);
عملگرهای تبدیل نوع این شکل را دارند:
static (explicit|implicit) operator <cast-to-type>(<cast-from-type> <parameter name>);
عملگرها همانند متدهای ایستا رفتار میکنند.
نمونههای نحوهی نگارش:
struct Point
{
decimal x;
decimal y;
public static bool operator ==(Point pt, Point ptOther)
{
return pt.x == ptOther.x && pt.y == ptOther.y;
}
public static bool operator !=(Point pt, Point ptOther)
{
return !(pt == ptOther);
}
public static Point operator *(Point pt, decimal scale)
{
var ptNew = new Point();
ptNew.x = pt.x * scale;
ptNew.y = pt.y * scale;
return ptNew;
}
public static implicit operator Point((decimal x, decimal y) xy)
{
var pt = new Point();
pt.x = xy.x;
pt.y = xy.y;
return pt;
}
public static explicit operator (decimal x, decimal y)(Point pt)
{
return (pt.x, pt.y);
}
}
اغلب کارساز است که متد Equals() را پیادهسازی کنید و آن را از عملگر == فراخوانی کنید. به همین ترتیب، برای مقایسهها میتوانید رابط IComparable را پیادهسازی کنید. در هر دو حالت، با کمی بیشتر از یک تیر، دو نشان میزنید.
باید توجه داشته باشید که نمیتوانید از نمادهایی که بخشی از مجموعهی استاندارد عملگرها نیستند، عملگر بسازید. فقط میتوانید از نمادهای موجود برای آن عملیاتی استفاده کنید که مستندات مشخص کرده قابل سربارگذاری هستند. عملگرهایی که میتوان سربارگذاری کرد اینجا فهرست شدهاند.
توجه کنید که ترتیب پارامترها در جایی که نوعشان متفاوت است مهم است. در کد نمونهی بالا، pt * 10m عبارتی مجاز است، در حالی که 10m * pt کامپایل نمیشود.
این مستنداتِ سربارگذاری عملگر نحوهی نگارش را به تفصیل توضیح میدهد.