一次線上問題引起的對於C#中相等判斷的思考

線上報來一個問題,說用戶的數據丟失了。開發通過緊張的調查。終於找到了緣由。測試

if (newData.GetValue(rowIndex) == oldData.GetValue(rowIndex))
{

   ..................

}


public object GetValue(string fieldName))
{
    ...............
return values[filedName]; //這是一個簡單類型: int,string }

 問題出在了 if 中的比較上。  values[rowIndex] 中保存的是一個整數,開發認爲兩個整數比較實用 ==  就能夠了。ui

可是 values[rowIndex] 中的整數通過 GetValue返回後被做爲 object 對象返回了,這時若是還使用 == 進行比較就會出現不等的狀況。spa

 

咱們來看一個更全面的例子:code

static void Main(string[] args)
{
    object value1 = new object();
    object value2 = new object();

    value1 = 2;
    value2 = 2;

    Console.WriteLine("value1  == value2 {0}", (value1 == value2).ToString());
    Console.WriteLine("vvalue1.Equals(value2) {0}", value1.Equals(value2).ToString());
    Console.WriteLine("Equals(value1, value2) {0}", Equals(value1, value2).ToString());
    Console.WriteLine("ReferenceEquals(value1,value2) {0}", ReferenceEquals(value1,value2).ToString());
}

運行結果對象

value1  == value2 False
value1.Equals(value2) True
Equals(value1, value2) True
ReferenceEquals(value1,value2) Falseblog

 

若是咱們將value1, value2 都定義爲數字,可是一個是long,一個是uint.開發

static void Main(string[] args)
{
    long value1 = 2;
     int value2 = 2;

     Console.WriteLine("value1  == value2 {0}", (value1 == value2).ToString());
     Console.WriteLine("value1.Equals(value2) {0}", value1.Equals(value2).ToString());
     Console.WriteLine("Equals(value1, value2) {0}", Equals(value1, value2).ToString());
     Console.WriteLine("ReferenceEquals(value1,value2) {0}", ReferenceEquals(value1,value2).ToString());

   }    

看一下運行結果 ,使用  ==  ,和 value1.Equals  方法比較是相等的。string

value1  == value2 True
value1.Equals(value2) True
Equals(value1, value2) False
ReferenceEquals(value1,value2) False

 

結合上面兩個例子,咱們定義一個long 變量, 一個unit 變量, 給它們賦值以後,再將這兩個變量賦值給兩個object 對象。it

 static void Main(string[] args)
 {
      object value1 = new object();
      object value2 = new object();

      long lgval = 2;
      int ival = 2;
            
      value1 = lgval;
      value2 = ival;
   
      Console.WriteLine("lgval  == ival {0}", (lgval == ival).ToString());
      Console.WriteLine("value1  == value2 {0}", (value1 == value2).ToString());
      Console.WriteLine("value1.Equals(value2) {0}", value1.Equals(value2).ToString());
      Console.WriteLine("Equals(value1, value2) {0}", Equals(value1, value2).ToString());
      Console.WriteLine("ReferenceEquals(value1,value2) {0}", ReferenceEquals(value1,value2).ToString());

}

能夠看到,除去值類型 lgval 和 uval 相等外,其它都是不相等的。io

lgval  == uval True
value1  == value2 False
value1.Equals(value2) False
Equals(value1, value2) False
ReferenceEquals(value1,value2) False

 是否是很抓狂? 到底什麼狀況下相等?什麼狀況下不等?咱們先將上面的結果總結一下。

 
 

value1 和value2都是Object 對象

含有相同類型的值對象(int)

含有相同的值

value1 是long,value2 是 int

含有相同的值

value1 和value2都是Object 對象

含有不一樣類型的值對象(long,int)

含有相同的值

value1  == value2
false  true   false
value1.Equals(value2)
true  true   false
Equals(value1, value2)
 true false   false
ReferenceEquals(value1,value2)
 false false   false

 

 

 

 

 

 

 

 

 

 

 

 

若是將一個值類型賦值給一個object 對象後,如何判斷相等? 微軟官方也沒有給出一個標準的說法。從測試的角度來看。

兩個比較的 object 中的內容若是類型相同,可使用Equals 來進行比較。

不過我我的仍是建議若是是比較值,仍是轉換爲對應的值類型進行比較,這樣比較清晰,不容易犯錯,你們也不用搞清楚 == 和 Equals 以前的細微差異。

 

ps: 若是object 的類型是 string , 上面的結果又會有所不一樣,有興趣的同窗能夠本身嘗試一下。

相關文章
相關標籤/搜索