2017-09-26 25 views
0

我想在下面的自定義類使用distinct:鮮明的自定義類型

public class RightOperandValue : IEquatable<RightOperandValue> 
{ 
    public string Value { get; set; } 
    public string DisplayName { get; set; } 

    public int GetHashCode(RightOperandValue obj) 
    { 
     int hashValue = Value == null ? 0 : Value.GetHashCode(); 
     int hashDisplayName = DisplayName == null ? 0 : DisplayName.GetHashCode(); 

     return hashValue^hashDisplayName; 
    } 

    public bool Equals(RightOperandValue other) 
    { 
     if (Value.Equals(other.Value) 
      && DisplayName.Equals(other.DisplayName)) 
     { 
      return true; 
     } 
     return false; 
    } 
} 

我試圖讓它們是「城市」和「城市」屬性Person.City的不同的值。

我嘗試以下方法:

 var values = _context 
      .Persons 
      .Select(x=>x.City) 
      .ToList(); 

     var rovs = values 
       .Select(x => new RightOperandValue() { DisplayName = x.Trim().ToLowerInvariant(), Value = x.Trim().ToLowerInvariant() }) 
       .Distinct() 
       .OrderBy(x => x.DisplayName) 
       .ToList(); 
     return rovs; 

其中給出了對顯示名稱和價值的價值「城市」 RightOperandValue的兩個實例。

我知道這似乎是一種迂迴的做事方式,但我最終需要Distinct來處理這個自定義類RightOperandValue。我讀了實施GetHashCode的,等於要做到這一點,但它似乎沒有工作

+4

我讀過這兩次,我仍然不知道你在問什麼。也許它只是我,但你可能想要清除你的問題 – maccettura

+0

我也困惑的問題。我的大腦告訴你看看像.Trim(),.ToUpper()或.String.Compare() –

+0

函數好吧我會盡力清理它。雅這有點不守規矩,對不起。 – pbordeaux

回答

2

的問題是,Distinct不使用Equals使用EqualsGetHashCode。除了它不會使用您的自定義實現(我不確定您是否試圖覆蓋GetHashCode那裏)。你需要重寫GetHashCode用這種方法簽名:

public override int GetHashCode() 
{ 
    // Your hashing algorithm here. 
} 

您當前的哈希算法是沒有好處,因爲它代表雖然。如果ValueDisplayName是相同的,它們將導致相同的散列。當你XOR相同散列在一起,你將會獲得0

+4

「問題是Distinct不使用等於它使用GetHashCode」 - 不,它使用兩者。雖然XOR散列並不好,但它仍然可以工作。 (它會正好工作,因爲* Equals和GetHashCode一樣。) –

+2

@Jason Boyd,請參閱[msdn上的這個註釋](https://msdn.microsoft.com/zh-cn/library/system.object。的GetHashCode(v = vs.110).ASPX#備註)。引用它「兩個相同的返回散列碼相同的對象,但相反的情況並非如此:相同的散列碼並不意味着對象相等,因爲不同的(不相等的)對象可能具有相同的散列碼。 'return 0;'是'GetHashCode'的有效實現;當然,這不應該以這種方式實現:一個好的散列函數可以快速給出不同輸入的結果(可能)和相同的結果輸入 –

+0

它*的確是OP的哈希算法不是很好。不好的散列造成的後果是,如果使用了更好的散列,它的速度會比它慢,並且速度會更慢,因爲更多的對象(平均而言)需要使用「Equals」方法。糟糕的散列不會阻止它產生正確的結果。 – Servy

1

問題是我沒有實現IEquatable正確

public class RightOperandValue : IEquatable<RightOperandValue> 
{ 
    public string Value { get; set; } 
    public string DisplayName { get; set; } 

    public bool Equals(RightOperandValue other) 
    { 
     if (Value == other.Value 
      && DisplayName == other.DisplayName) 
     { 
      return true; 
     } 
     return false; 
    } 

    public override int GetHashCode() 
    { 
     int hashValue = Value == null ? 0 : Value.GetHashCode(); 
     int hashDisplayName = DisplayName == null ? 0 : DisplayName.GetHashCode(); 

     return hashValue^hashDisplayName; 
    } 

} 
+0

另外, Equals'方法將更簡單地返回爲'return Value == other.Value && DisplayName == other.DisplayName;' - 在這種情況下,您可以使用表達式成員來實現它。 –