【问题标题】:How can I compare two objects of same class? [duplicate]如何比较同一类的两个对象? [复制]
【发布时间】:2014-01-12 10:33:43
【问题描述】:

我想知道如何像string.Compare() 方法那样比较两个对象(属于同一类)。

有没有办法做到这一点?

【问题讨论】:

标签: c# .net oop object


【解决方案1】:

可以检查两个相等Reference Equality和Value Equality

引用相等

引用相等意味着两个对象引用引用同一个底层对象。这可以通过简单的赋值来实现,如下例所示。

class Test
{
    public int Num { get; set; }
    public string Str { get; set; }

    static void Main()
    {
        Test a = new Test() { Num = 1, Str = "Hi" };
        Test b = new Test() { Num = 1, Str = "Hi" };

        bool areEqual = System.Object.ReferenceEquals(a, b);
        // Output will be false
        System.Console.WriteLine("ReferenceEquals(a, b) = {0}", areEqual);

        // Assign b to a.
        b = a;

        // Repeat calls with different results.
        areEqual = System.Object.ReferenceEquals(a, b);
        // Output will be true
        System.Console.WriteLine("ReferenceEquals(a, b) = {0}", areEqual);


    }
}

价值平等

值相等意味着两个对象包含相同的值或多个值。对于 int 或 bool 等原始值类型,值相等的测试很简单。

【讨论】:

    【解决方案2】:
    public class BaseEntity
    {
        public int Id { get; set; }
    }
    
    public class Product : BaseEntity
    {
       public string Name { get; set; }
       public decimal Price { get; set; }
    }
    
    //Generic Comparer
    public class EntityComparer<T> :  IEqualityComparer<T>, IComparer<T> 
    where T : BaseEntity
    {
        public enum AscDesc : short
        {
            Asc, Desc
        }
    
        #region Const
        public string PropertyName { get; set; }
        public AscDesc SortType { get; set; }
        #endregion
    
        #region Ctor
        public EntityComparer(string _propertyname = "Id", AscDesc _sorttype = AscDesc.Asc)
        {
            this.PropertyName = _propertyname;
            this.SortType = _sorttype;
        }
        #endregion
    
        #region IComparer
        public int Compare(T x, T y)
        {
            if (typeof(T).GetProperty(PropertyName) == null)
                throw new ArgumentNullException(string.Format("{0} does not contain a property with the name \"{1}\"", typeof(T).Name, PropertyName));
    
            var xValue = (IComparable)x.GetType().GetProperty(this.PropertyName).GetValue(x, null);
            var yValue = (IComparable)y.GetType().GetProperty(this.PropertyName).GetValue(y, null);
    
            if (this.SortType == AscDesc.Asc)
                return xValue.CompareTo(yValue);
    
            return yValue.CompareTo(xValue);
        }
        #endregion
    
        #region IEqualityComparer
        public bool Equals(T x, T y)
        {
            if (typeof(T).GetProperty(PropertyName) == null)
                throw new InvalidOperationException(string.Format("{0} does not contain a property with the name -> \"{1}\"", typeof(T).Name, PropertyName));
    
            var valuex = x.GetType().GetProperty(PropertyName).GetValue(x, null);
            var valuey = y.GetType().GetProperty(PropertyName).GetValue(y, null);
    
            if (valuex == null) return valuey == null;
    
            return valuex.Equals(valuey);
        }
    
        public int GetHashCode(T obj)
        {
            var info = obj.GetType().GetProperty(PropertyName);
            object value = null;
            if (info != null)
            {
                value = info.GetValue(obj, null);
            }
    
            return value == null ? 0 : value.GetHashCode();
        }
        #endregion
    }
    
     //Usage
     Product product = new Product();
     Product product2 =new Product();
     EntityComparer<Product> comparer = new EntityComparer<Product>("Propert Name Id Name whatever u want", Asc Or Desc);
     comparer.Compare(product, product2);
    

    【讨论】:

      【解决方案3】:

      因为对象是引用类型,所以你应该使用 obj.Equals() 方法。 另请注意:

      string.ReferenceEquals(str, str2);
      

      它显然是比较参考文献。

      str.Equals(str2) 
      

      首先尝试比较参考。然后它会尝试按值进行比较。

      str == str2
      

      和 Equals 一样。

      【讨论】:

        【解决方案4】:

        您需要实现 IComparable 接口。

        private class sortYearAscendingHelper : IComparer
        {
           int IComparer.Compare(object a, object b)
           {
              car c1=(car)a;
              car c2=(car)b;
              if (c1.year > c2.year)
                 return 1;
              if (c1.year < c2.year)
                 return -1;
              else
                 return 0;
           }
        }
        

        原帖可以找到Here

        【讨论】:

          【解决方案5】:

          你可以实现IComparable接口,就像建议的here

          public class Temperature : IComparable 
          {
              // The temperature value 
              protected double temperatureF;
          
              public int CompareTo(object obj) {
                  if (obj == null) return 1;
          
                  Temperature otherTemperature = obj as Temperature;
                  if (otherTemperature != null) 
                      return this.temperatureF.CompareTo(otherTemperature.temperatureF);
                  else 
                     throw new ArgumentException("Object is not a Temperature");
              }
            ...
          

          source

          您将拥有CompareTo 方法,该方法将比较您班级的项目。有关IComparable 的更多信息,请访问SO。拥有CompareTo,您可以根据here 中提到的比较函数对对象列表进行排序

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2021-04-29
            • 1970-01-01
            • 2015-07-26
            • 2017-09-23
            • 1970-01-01
            • 1970-01-01
            • 2010-11-22
            相关资源
            最近更新 更多