2012-10-05 58 views
0
var resultList = list1.Intersect<XElement>(list2, new XElementComparer()); 

爲什麼我的XElementComparer的GetHashCode方法從來沒有調用?Linq`s Intersect不調用GetHashCode

當我檢查resultList我看到的內容:

System.Exeception object to set to an instance of an object 

我的兩個列表有XElements。我錯了什麼?

+1

這將有助於添加的'XElementComparer' –

+0

實現你怎麼知道它不是調用'GetHashCode'?這聽起來好像根本就沒有工作...... – Servy

+0

你如何「檢查resultList的內容」?你可以在這樣做的例外情況下提供堆棧跟蹤嗎? – Iridium

回答

3

Intersect擴展方法返回一個IEnumerable<>,但直到在開始枚舉它(例如做一個foreach,呼叫.ToList()等)並不實際執行的交叉點。因此,我不希望你的比較器上的任何方法都基於你給出的代碼片段被調用,因爲你沒有枚舉結果。

+0

你是對的:) – Elisabeth

+0

不是_當我檢查resultList_的內容時,是否枚舉了結果? –

+1

@AustinSalonen - 是的,但如果OP是檢查是否的GetHashCode是通過將一個斷點叫,和「檢查[和]的resultList的內容」是通過手錶/調試工具提示或類似的調試器的功能,這將導致沒有斷點的評估。這可能是一個延伸,但完全基於*代碼*呈現沒有評估正在發生。 – Iridium

0

我敢打賭,它正在呼籲您執行GetHashCode該實現(或Equals)正在拋出一個NullReferenceException。 我們真正能夠回答您的問題的唯一方法是讓您包含XElementComparer的代碼。

我跑了快速測試,其產生這樣的輸出:

的Equals計數= 1; GetHashCode的數量= 6

[Test] 
public void X() 
{ 
    var list1 = new List<Alpha> {new Alpha {Bravo = 1}, new Alpha {Bravo = 1}, new Alpha {Bravo = 2}}; 
    var list2 = new List<Alpha> { new Alpha { Bravo = 1 }, new Alpha { Bravo = 3 }, new Alpha { Bravo = 5 } }; 

    var alphaComparer = new AlphaComparer(); 

    Assert.AreEqual(1, list1.Intersect(list2, alphaComparer).Count()); 
    Console.WriteLine("Equals count = {0}; GetHashCode count = {1}", alphaComparer.EqualsCallCount, alphaComparer.GetHashCodeCallCount); 
} 

class Alpha 
{ 
    public int Bravo { get; set; } 
} 

class AlphaComparer : IEqualityComparer<Alpha> 
{ 
    public int EqualsCallCount { get; private set; } 
    public int GetHashCodeCallCount { get; private set; } 

    public bool Equals(Alpha x, Alpha y) 
    { 
     EqualsCallCount += 1; 
     return x.Bravo.Equals(y.Bravo); 
    } 

    public int GetHashCode(Alpha obj) 
    { 
     GetHashCodeCallCount += 1; 
     return obj.Bravo.GetHashCode(); 
    }