اندازهی قلم متن
تخمین مدت زمان مطالعهی مطلب:
دو دقیقه
روش سنتی بررسی نال بودن اشیاء و متغیرها در زبان #C، استفاده از اپراتور == است:
اما از زمان C# 7.0 و معرفی pattern matching، از واژهی کلیدی is نیز میتوان برای اینکار استفاده کرد (که به آن constant pattern هم میگویند):
اکنون سؤال اینجا است که امروز بهتر است از کدامیک استفاده کنیم؟
سربارگذاری عملگرها و مقایسهی وهلههای اشیاء با null
در عمل، تفاوتی بین استفادهی از عملگر == و واژهی کلیدی is برای بررسی نال بودن وهلهای از یک شیء وجود ندارد؛ اما ... با یک شرط! فقط در حالتیکه عملگر == سربارگذاری نشده باشد.
برای نمونه کلاس Person زیر را در نظر بگیرید که عملگرهای == و =! آن بازنویسی شدهاند:
در این حالت اگر قطعه کد زیر را اجرا کنیم که در یک سطر آن، وهلهی person که مقدار نال را دارد، توسط عملگر == با null مقایسه شدهاست و در سطر بعدی با کمک واژهی کلیدی is با نال مقایسه شدهاست:
به نظر شما خروجی این قطعه کد چیست؟
اگر در کلاس Person سربارگذاری عملگر == صورت نمیگرفت، خروجی زیر را مشاهده میکردیم:
اما اینبار خروجی واقعی قطعه کد فوق، با چیزی که انتظار داریم متفاوت است:
مزیت کار با واژهی کلیدی is، صرفنظر کردن از operator overloads یا همان سربارگذاری عملگرها است. در حین حالت فقط مقدار person، با null مقایسه میشود و دیگر، کار به بررسی خروجی false زیر نمیرسد (کاری که با استفاده از عملگر == حتما انجام خواهد شد):
به عبارتی استفادهی از عملگر == جهت مقایسهی با null، حتما نیاز به بررسی کدهای کلاس Person را جهت مشاهدهی کدهای تغییر یافتهی عملگر == را نیز دارد؛ اما زمانیکه از وژهی کلیدی is استفاده میکنیم، مقصود اصلی ما را که بررسی مقدار جاری با null است، برآورده میکند (و در 99 درصد موارد، ما هدف دیگری را دنبال نمیکنیم و برای ما مهم نیست که عملگر == سربارگذاری شدهاست یا خیر). همچنین سرعت مقایسه در حالت استفاده از واژهی کلیدی is نیز بیشتر است؛ چون دیگر فراخوانی کدی که عملگر == را سربارگذاری میکند، صورت نخواهد گرفت و از زمان C# 9.0، برای حالت بررسی حالت عکس آن میتوان از if (obj is not null) نیز استفاده کرد (بجای if (!(obj is null))) که از حالت سربارگذاری عملگر =! صرفنظر میکند.
یک نکته: null coalescing operator یعنی ?? و null coalescing assignment operator یعنی =?? نیز همانند واژهی کلیدی is عمل میکنند. یعنی از == سربارگذاری شده صرفنظر خواهند کرد.
if(person == null) { }
if(person is null) { }
سربارگذاری عملگرها و مقایسهی وهلههای اشیاء با null
در عمل، تفاوتی بین استفادهی از عملگر == و واژهی کلیدی is برای بررسی نال بودن وهلهای از یک شیء وجود ندارد؛ اما ... با یک شرط! فقط در حالتیکه عملگر == سربارگذاری نشده باشد.
برای نمونه کلاس Person زیر را در نظر بگیرید که عملگرهای == و =! آن بازنویسی شدهاند:
public class Person { public static bool operator ==(Person x, Person y) { return false; } public static bool operator !=(Person x, Person y) { return !(x == y); } public override bool Equals(object obj) { return base.Equals(obj); } }
Person person = null; Console.WriteLine("Is Person null?"); Console.WriteLine($"== says: {person == null}"); Console.WriteLine($"is says: {person is null}");
اگر در کلاس Person سربارگذاری عملگر == صورت نمیگرفت، خروجی زیر را مشاهده میکردیم:
Is Person null? == says: True is says: True
Is Person null? == says: False is says: True
public static bool operator ==(Person x, Person y) { return false; }
یک نکته: null coalescing operator یعنی ?? و null coalescing assignment operator یعنی =?? نیز همانند واژهی کلیدی is عمل میکنند. یعنی از == سربارگذاری شده صرفنظر خواهند کرد.