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

时间:2013-12-30 08:02:56

标签: c# dictionary override equals

如何覆盖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 个答案:

答案 0 :(得分:2)

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

  1. 检查简单案例(例如obj == null
  2. 使用作为而不是 + ()
  3. 如果没有 throw
  4. ,请不要抓住所有例外情况
  5. 三个不同的属性进行比较时,不要使用 Reflection
  6. 可能的实施可以是

      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
      }