【问题标题】:Compare 2 class objects and ignore 1 (or more) property?比较 2 个类对象并忽略 1 个(或更多)属性?
【发布时间】:2018-11-16 10:33:48
【问题描述】:

所以我创建了一个这样的类:

public class ClassName
{
public int ID;

public String n_1 {get; set; }
public String n_2 {get; set; }
// ....
public String n_x {get; set; }
}

稍后在我的代码中,我比较了 2 个ClassName 对象:

ClassName Item_1 /*...*/ ;
ClassName Item_2 /*...*/ ;

像这样:

if (Item_1 != Item_2 && Item_1.n_a == Item_2.n_a)
{
//do something
}

现在我的问题是 Item_1.IDItem_2.ID 应该被忽略。有没有简单的方法来做到这一点?我想出的唯一解决方案是不费吹灰之力

if ( (Item_1.n_1 != Item_2.n_1 || Item_1.n_2 != Item_2.n_2 || /* ... */ ) && Item_1.n_a == Item_2.n_a)

【问题讨论】:

  • 这有什么问题?如果您正在进行手动比较并且您已经忽略了ID
  • 你应该检查IComparable<T>接口
  • 通过Item_1 != Item_2,您实际上不会检查两个对象的所有属性是否不相等,它只会检查存储在Item_1Item_2中的引用是否不相等。
  • @axbeit 我在答案中添加了一些解释,您可以查看,如果您有任何问题,请随时提问。

标签: c# class if-statement compare


【解决方案1】:

覆盖类中的 object.Equals 方法并指定您希望如何比较它。

然后用!Item1.Equals(Item2)代替!=

https://docs.microsoft.com/en-us/dotnet/api/system.object.equals?view=netframework-4.7.2

【讨论】:

    【解决方案2】:

    简单的方法就是你实际在做什么,只需创建一个这样的方法

        public bool Method(ClassName Item_1,ClassName Item2)
        {
        bool check=false;
        if ( (Item_1.n_1 != Item_2.n_1 || Item_1.n_2 != Item_2.n_2 || /* ... */ ) && Item_1.n_a == Item_2.n_a)
        check=true
    
    return check
        }
    

    【讨论】:

    • @mjwills 嗨。 IComparer 方式似乎类似于“不费吹灰之力”。我仍然必须手动编写所有内容。是否有自动填充选项?
    • 有没有办法减少手动操作?就在这里。但老实说,这比 matteo 在这里建议的要多得多(一次性)。如果您确实想以艰难的方式做到这一点,请使用stackoverflow.com/a/986617/34092 作为起点@axbeit。
    【解决方案3】:

    要执行Item_1 != Item_2Item_1 == Item_2 之类的操作并获取所有属性(或您想要的属性)进行比较,您需要实现自己的Equals 方法和==!= 运算符重载。

    == 运算符,来自 MSDN

    对于字符串以外的引用类型,== 如果它的两个操作数引用同一个对象,则返回 true。

    为此,您可以从一些简单的解决方案开始,实现IEquatable&lt;T&gt; 接口,在Equals 方法中填充您的比较逻辑,并在内部调用您的类型安全Equals 方法重载==!= 运算符:

    public class ClassName : IEquatable<ClassName>
    {
        public int ID;
    
        public String n_1 { get; set; }
        public String n_2 { get; set; }
        // ....
        public String n_x { get; set; }
    
        public static bool operator ==(ClassName obj1, ClassName obj2)
        {
            if (((object)obj1) == null || ((object)obj2) == null)
                return Equals(obj1, obj2);
            return obj1.Equals(obj2);
        }
    
        public static bool operator != (ClassName obj1, ClassName obj2)
        {
            if (((object)obj1) == null || ((object)obj2) == null)
                return !Equals(obj1, obj2);
            return !obj1.Equals(obj2);
        }
    
    
        public bool Equals(ClassName obj)
        {
            if (obj == null) return false;
    
            return (n_1 == obj.n_1) && (n_2 == obj.n_2) && (n_x == obj.n_x); //you can ignore ID here
        }
    
        public override bool Equals(object obj)
        {
            if (obj == null)
                return false;
    
            ClassName classNameObj = obj as ClassName;
            if (classNameObj == null)
                return false;
            else
                return Equals(classNameObj);
        }
    
        public override int GetHashCode()
        {
            //This code was generated by VS ide, you can write your own hashing logic
            var hashCode = 1032198799;
            hashCode = hashCode * -1521134295 + ID.GetHashCode();
            hashCode = hashCode * -1521134295 + EqualityComparer<string>.Default.GetHashCode(n_1);
            hashCode = hashCode * -1521134295 + EqualityComparer<string>.Default.GetHashCode(n_2);
            hashCode = hashCode * -1521134295 + EqualityComparer<string>.Default.GetHashCode(n_x);
            return hashCode;
        }
    }
    

    然后你可以签入你的if

    if (Item_1 != Item_2)
    {
        //Do Something
    }
    

    对于Equals方法,你应该坚持Guidelines for Overriding Equals() and Operator ==

    参考:== Operator!= OperatorIEquatable InterfaceIEquatable.Equals(T) MethodGuidelines for Overriding Equals() and Operator ==

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多