C#ValueType等于不比较属性?

时间:2014-02-23 08:53:16

标签: c#

以下打印件等于:

struct A
{
    int x;
    public A(int _x) { x = _x; }
    public int Y
    {
        get
        {
            Random r = new Random();
            return r.Next(0, 1000);
        }
    }
}

static void Main(string[] args)
{
    A a1 = new A(1),a2 = new A(1);
    if (a1.Equals(a2))
    {
        Console.Write("Equals");
    }
    else
    {
        Console.Write("Different");
    }
}

在这种情况下,有没有让C#返回false?意思是,在比较值类型时采用所考虑的属性?

4 个答案:

答案 0 :(得分:3)

写入相等然后点击“tab”按钮两次:

// override object.Equals
        public override bool Equals(object obj)
        {


            if (obj == null || GetType() != obj.GetType())
            {
                return false;
            }

            // TODO: write your implementation of Equals() here
            throw new NotImplementedException();
            return base.Equals(obj);
        }

这是一个自动生成的代码段。现在你可以尝试类似的东西:

// override object.Equals
        public override bool Equals(object obj)
        {

            // checks for A versus A    
            if (obj == null || GetType() != obj.GetType())
            {
                return false;
            }

            // TODO: write your implementation of Equals() here
            throw new NotImplementedException();
            int compareThis=(A)obj.x;
            return ((A)base).x==compareThis; // maybe casting is not needed
        }

答案 1 :(得分:1)

建议的方法是使用IEquatable<T>而不是使用默认的继承Equals方法。 IEquatable泛型接口定义一个通用方法,值类型或类实现该方法以创建特定于类型的方法来确定实例的相等性。

  using System;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            A a1 = new A(1), a2 = new A(1);
            //here  the  CLR  will do a lot of unboxing and check operations via reflection in  order to make a comparaison between fields value. 
            //just take a look bellow  at the decompiled default Equals method how it's  done 
            if (a1.Equals(a2))
            {
                Console.Write("Equals");
            }
            else
            {
                Console.Write("Different");
            }
        }
    }

   public  struct A : IEquatable<A>
    {
        int x;
        public A(int _x) { x = _x; }
        public int Y
        {
            get
            {
                Random r = new Random();
                return r.Next(0, 1000);
            }
        }
         //here no boxing or  unboxing is needed  even if is a value  type  and the CLR will call this method first 
        public bool Equals(A other)
        {
            return this.Y == other.Y;   
        }
        public override bool Equals(object obj)
        {
            //this is  why a bad approach to compare both objects  you  need to unbox the struct arguments wich hurting  performance 
            return this.Y == ((A)obj).Y;
        }

       public override int GetHashCode()
       {
           return base.GetHashCode();
       }

       //default  implementation 
        //public override bool Equals(object obj)
        //{
        //    return base.Equals(obj);
        //}
    }
}

CLR实施

CLR下面发生了什么

 public override bool Equals(object obj)
    {
      if (obj == null)
        return false;
      RuntimeType runtimeType = (RuntimeType) this.GetType();
      if ((RuntimeType) obj.GetType() != runtimeType)
        return false;
      object a = (object) this;
      if (ValueType.CanCompareBits((object) this))
        return ValueType.FastEqualsCheck(a, obj);
      FieldInfo[] fields = runtimeType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
      for (int index = 0; index < fields.Length; ++index)
      {
        object obj1 = ((RtFieldInfo) fields[index]).UnsafeGetValue(a);
        object obj2 = ((RtFieldInfo) fields[index]).UnsafeGetValue(obj);
        if (obj1 == null)
        {
          if (obj2 != null)
            return false;
        }
        else if (!obj1.Equals(obj2))
          return false;
      }
      return true;
    }

答案 2 :(得分:0)

这与this问题非常相似 您需要做的就是覆盖Equals方法:

struct A
{
    int x;
    public A(int _x) { x = _x; }
    public int Y
    {
        get
        {
            Random r = new Random();
            return r.Next(0, 1000);
        }
    }


       public override bool Equals(object obj) 
       {
          //compare whatever you want...

       }

    }
}

答案 3 :(得分:0)

覆盖等于方法并根据属性比较返回true或false。