︿
Top

2019年8月14日 星期三

[C#] 如何進行變數或物件的 相同(ReferenceEquals) 或相等(Equals) 的比較: 由 int / string 的原始程式碼談起


0. 前言


在撰寫單元測試時, 常會需要作 expected 與 actual 的比較, 常用的是 Assert.AreSame() 或 Assert.AreEqual().

關於 AreSame() 的部份, 很容易理解, 就是同一個記憶體區塊. 例如:

void Main()
{
    var a = new Customer();
    var b = a;
    Console.WriteLine(Object.ReferenceEquals(a, b));
}
public class Customer
{
    public int Id { get; set; }
    public string Name {get; set; }
}
則 變數 b 與 變數 a 是相同的, 因為指向同一個 Customer 物件.
即 Object.ReferenceEqual(a,b) 會回傳 True.

關於 AreEqual() 的部份, 則會因對於相等的定義不同, 而有不同的結果. 例如:
有 2 個 Box (具有長/寬/高/顏色 4 個屬性), 我們可以定義它的相等是:

  • 長/寬/高 都各自相等即可
  • 長/寬/高 都各自相等之外, 顏色也要相等
因此, 會有不同各自認定的規則, 來確定是否相等.

在 "相等" 的實作方面, 網路上查到了 91 哥的 2 篇文章 (參考文件2 / 參考文件3). 有提到可採用一些的方式作轉換後, 進行比較, 例如:

  • 覆寫 Object 類別的 Equals() / GetHashCode()
  • 轉換成匿名型別, 再作比較
  • 轉換成 Expected Objects, 再作比較

本篇文章的編排比較類似個人的筆記, 說明會放在程式碼裡, 或圖片即能理解, 就不多作說明, 主要內容為:

  • 由 int / string 等內建的資料型別, 如何達到 "相等" 的比較開始談起
  • 再延伸至自訂類別, 如何達到 "相等" 的比較
  • Dictionay<T> 是如何作到去掉重複
  • LINQ 的 OrderBy() 是如何作到的