2015-04-04 37 views
0

考慮以下幾點:爲對象陣列中平等字符串比較:意想不到假

using System; 

namespace ObjectArrayWeirdness 
{ 
    public class Program 
    { 
     public static object[] Change(object[] set) 
     { 
      object[] result = new object[set.Length]; 

      // If the following two lines are replaced with: 
      // result[0] = "ab"; 
      // then ArrayEquals will evaluate true. 
      result[0] = "a"; 
      result[0] += "b"; 
      return result; 
     } 

     public static bool ArrayEquals(object[] a, object[] b) 
     { 
      if (a.Length != b.Length) return false; 
      for (int i = 0; i < a.Length; i++) 
      { 
       if (a[i] != b[i]) 
       { 
        return false; 
       } 
      } 
      return true; 
     } 


     static void Main(string[] args) 
     { 
      object[] expected = { "ab" }; 
      object[] actual = Change(new object[] { 1 }); 
      Console.WriteLine(ArrayEquals(expected, actual)); 
     } 
    } 
} 

Dotnetfiddle for convenience

輸出:

輸出 result[0].GetType()
false 

System.String 

我的問題:

  1. 是否在ArrayEquals比較失敗,因爲它是比較對象引用,而不是價值?

  2. 如果是這樣的話,爲什麼在正確的字符串被分配到一個步驟(不使用+=)到result[0]時成功?

我必須承認我預期的正常字符串比較鑑於GetType()標識都a[0]b[0]爲字符串。

回答

4

ArrayEquals中的比較失敗是因爲它比較對象引用而不是值嗎?

如果是這樣的話,爲什麼它在正確的字符串中的一個步驟分配成功(不使用+ =)到結果[0]?

這是一個編譯器優化。當您在編譯時聲明兩個相同的文字字符串時,編譯器將其摺疊爲單個對象實例以節省空間。但是,如果字符串是在運行時構建的,則最終會有兩個單獨的字符串對象。

+0

非常感謝! – 2015-04-04 00:24:26

1

到底發生了什麼。您正在比較對象引用。但請注意,該字符串會覆蓋==!=運算符以比較文字。因此,如果您將陣列項目投射到字符串,您的比較將按預期工作:

if ((string)a[i] != (string)b[i]) 
{ 
    return false; 
} 
+0

謝謝!是的,我在後面的代碼中添加了'.ToString()',只是想清楚發生了什麼。 – 2015-04-04 00:42:28

+1

是的,我同意理解問題的根源更重要,然後解決它。而且@JohnWu對實際發生的事情給出了很好和清楚的解釋。 – PiotrWolkowski 2015-04-04 00:46:17