与自定义类型不同

时间:2017-09-26 18:44:46

标签: c# linq

我正在尝试在以下自定义类上使用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的不同值,它们是&#34; CITY&#34;和&#34;城市&#34;。

我尝试以下方法:

        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;

它给出了两个具有&#34; city&#34;的RightOperandValue实例。对于DisplayName和Value的值。

我知道这似乎是一种迂回的做事方式,但我最终需要Distinct来处理这个自定义类RightOperandValue。我读到实现GetHashCode和Equals是实现它的方法,但它似乎不起作用

2 个答案:

答案 0 :(得分:2)

问题是Distinct 不使用Equals 使用Equals GetHashCode。除非它不会使用您的自定义实现(我不确定您是否尝试覆盖GetHashCode)。您需要使用此方法签名覆盖GetHashCode

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

您当前的哈希算法并不是很好。如果ValueDisplayName相同,则会产生相同的哈希值。当你对同一个哈希进行异或时,你会得到0。

答案 1 :(得分: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;
    }

}