首页 文章

使用Dictionary覆盖对象的等于 . C#

提问于
浏览
1

如何重写Equals,这样你可以比较两个相同的类和两个目录而不用静态指定它们?目前,有一个由以下字段组成的对象 . 对于类型字符串,Int32等,等于满足条件 .

public class RatiosAVG
{
    public RatiosAVG()
    {
        Dict1 = new Dictionary<Int32, OtherObject1>();
        Dict2 = new Dictionary<Int32, OtherObject2>();
    }

    public OtherObject1 Obj { get; set; }
    public Dictionary<Int32, OtherObject1> Dict1 { get; set; }
    public Dictionary<Int32, OtherObject2> Dict2 { get; set; }
    public String Name { get; set; }
    public Int32 Value { get; set; }

    public override bool Equals(Object obj)
    {
        try
        {
            if (!(obj is RatiosAVG))
                return false;

            RatiosAVG other = (RatiosAVG)obj;
            Type type = typeof(RatiosAVG);
            foreach (System.Reflection.PropertyInfo property in type.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance))
            {

                Object selfValue = type.GetProperty(property.Name).GetValue(this, null);
                Object otherValue = type.GetProperty(property.Name).GetValue(other, null);

                if ((selfValue == null || !selfValue.Equals(otherValue)) && selfValue != otherValue)
                        return false;
            }

            if (type.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance).Count() == 0) 
               return false; 
            else 
               return true;
        }
        catch (Exception) { return false; }
    }
}

OtherObject1和OtherObject2是Object

1 回答

  • 2

    您的代码中存在许多问题:

    • 检查简单案例(例如 obj == null

    • 使用 as 而不是 is ()

    • 不抛弃所有异常

    • 当有三个不同的属性进行比较时,不要使用Reflection

    可能的实现可以

    public override Boolean Equals(Object obj) {
        // If obj is actually "this" then true
        if (Object.ReferenceEquals(this, obj))
          return true;
    
        // "as " is better the "is" + "(RatiosAVG)" 
        RatiosAVG other = obj as RatiosAVG;
    
        // obj is either null or not a RatiosAVG
        if (Object.ReferenceEquals(null, other))
          return false;
    
        // When you have 3 properties to compare, reflection is a bad idea 
        if (other.Value != Value)
          return false;
        else if (!String.Equals(other.Name, Name, StringComparison.Ordinal))
          return false;
        else if (!Object.Equals(other.Obj, Obj))
          return false;
    
        // Finally, dictionaries. If, the criterium is: 
        // "Dictionaries are considered being equal if and only 
        // if they have the same {key, value} pairs"
        // you can use Linq: SequenceEqual. 
        // Otherwise you should provide details for the dictionaries comparison
        if (!Enumerable.SequenceEqual(other.Dict1, Dict1))
          return false;
        else if (!Enumerable.SequenceEqual(other.Dict2, Dict2))
          return false;
    
        return true;
      }
    
      // Do not forget to override GetHashCode:
      public override int GetHashCode() {
        return Value; // <- Simplest version; probably you have to put more elaborated one
      }
    

相关问题