2010-11-08 68 views
3

我有一個複合控件中的一個屬性,它檢查值是否在實際設置相關的專用域和做其他事情之前是否已經改變。評估設置器中的值甚至沒有被檢查

但是,它似乎從未評估該陳述。

下面是屬性的代碼:我已經通過代碼加強

public T SearchCriteria 
     { 
      get 
      { 
       return mySearchCriteria; 
      } 
      set 
      { 
       if (value != mySearchCriteria) 
       { 
        mySearchCriteria = value; 
        EnsureChildControls(); 
        SearchGridParser parser = SearchGridParserFactory.GetParser(this.Type); 
        parser.SetSearchPanelControls<T>(this.mySearchCriteria, ref mySearchParametersPanel); 
        GridView.PageIndex = 0; 
       } 
      } 
     } 

,並且每次它進入「價值= mySearchCriteria!」它的計算結果爲假,並跳過if語句中的代碼。事實上,即使我將其更改爲「value == mySearchCriteria」,它也會這樣做,如果只是完全跳過它,無論它如何評估!

嘿?

我試過改變檢查中的參數順序,也使用object.Equals()但這些更改都沒有任何區別。

我重寫了Equals,!=,==和GetHashCode。

在代碼中還有其他地方使用「==」和「!=」來表示這些對象類型沒有問題,所以我知道我的覆蓋工作正常。

問題是,這甚至沒有命中覆蓋的方法。我在「==」,「!=」,「Equals」和「GetHashCode」上放置了中斷,並且在評估「value!= mySearchCriteria」語句時,它們都不會被調用。

這就像它完全跳過評估它。

回答

4

在泛型類型間使用==幾乎總是一個壞主意。運算符是超載而不是覆蓋,所以即使實際類型中存在==運算符,編譯器也不會知道它。 (這意味着你的要求,你已經「覆蓋」 ==!=已經是不正確 - 你已經超負荷的經營者應該確保你理解上的差異,因爲它是非常重要的。)

當你寫:

在代碼中還有其他地方使用「==」和「!=」來表示這些對象類型沒有問題,所以我知道我的覆蓋工作正常。

我懷疑這些區域不是泛型代碼......它們是編譯器知道正在比較哪些類型的地方,所以知道要使用您的重載。這與你的一般情況有很大的不同,編譯器不知道知道如何使用==,所以回退到引用標識。

我假設你有一個通用約束條件where T : class或者你的代碼根本無法編譯 - 但它仍然只是執行參考比較,而不是使用實際類型的T提供的任何超載。

使用EqualityComparer.Default<T>.Equals(value, mySearchCriteria)可以使用Equals的重寫實現,包括IEquatable<T>

+0

非常感謝!這完美的作品!我幾個小時一直在抨擊我的頭,謝謝你,謝謝你,謝謝。 =) – 2010-11-08 15:38:09

+0

@Amanda:值得回顧一下,並確保你理解它背後的原因 - 特別是重載和重寫之間的差異,以及特殊代碼中的影響。 – 2010-11-08 15:39:09