تفاوت میان اپراتور == و تابع 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 استفاده کنید. این را در نظر داشته باشید که در هنگام کار با نوعهای جدید یا نوشتن الگوریتمهای عمومی، این تفاوت به شما در انتخاب صحیح کمک خواهد کرد.