تفاوت میان اپراتور == و تابع Equals در C# چیست؟
زمانی که از عملگر ==
برای مقایسه اشیا استفاده میشود، مخصوصاً زمانی که طرف چپ مقایسه از نوع object
باشد، این عملگر به System.Object.ReferenceEquals
ارجاع میدهد. این بدان معناست که ==
در واقع به مقایسه آدرسهای حافظه (reference) میپردازد، نه محتویات اشیا. به علاوه، میتوان گفت که عملگر ==
با توجه به نوع داده در سمت چپ در زمان کامپایل تصمیمگیری میکند و در این حالت چون نوع چپ object
است، هر نوع عملیات مربوط به همتای خود (مثلاً برای string
) نادیده گرفته میشود.
اما از سویی دیگر، متد .Equals()
یک متد مجازی است و هر نوع داده میتواند این متد را بازنویسی کند. در مورد رشتهها (strings)، متد .Equals()
به مقایسه محتویات واقعی رشتهها میپردازد. بنابراین، اگر دو رشته حتی از لحاظ نشانه (reference) متفاوت باشند، اگر محتوای آنها یکسان باشد، این متد true
برمیگرداند.
به عنوان مثال، کد زیر نشاندهنده تفاوتهای ظریف در رفتار میان ==
و .Equals()
است:
string s1 = "test";
string s2 = "test";
string s3 = "test1".Substring(0, 4);
object s4 = s3; // توجه: تنظیم شده به متغیر object!
Console.WriteLine($"{object.ReferenceEquals(s1, s2)} {s1 == s2} {s1.Equals(s2)}");
Console.WriteLine($"{object.ReferenceEquals(s1, s3)} {s1 == s3} {s1.Equals(s3)}");
Console.WriteLine($"{object.ReferenceEquals(s1, s4)} {s1 == s4} {s1.Equals(s4)}");
خروجی این کد به شکل زیر خواهد بود:
True True True // s1, s2
False True True // s1, s3
False False True // s1, s4
چنانچه در مقایسهها مشاهده میشود، در مقایسهی s1 با s2، هم ==
و هم .Equals()
به true
برمیگردند چرا که هر دو به محتوای یکسان اشاره دارند. با این حال، در مقایسه بین s1
و s3
، ==
به true
و .Equals()
نیز به true
برمیگردد، در حالی که در مقایسه با s4
، ==
یک false
و .Equals()
یک true
تولید میکند.
برای جمعبندی، اگر میخواهید مقادیر را مقایسه کنید، بهرهگیری از .Equals()
بهترین انتخاب است، در حالی که اگر به بررسی این که آیا دو متغیر به یک شیء خاص اشاره دارند نیاز دارید، باید از Object.ReferenceEquals
استفاده کنید. این را در نظر داشته باشید که در هنگام کار با نوعهای جدید یا نوشتن الگوریتمهای عمومی، این تفاوت به شما در انتخاب صحیح کمک خواهد کرد.