Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 实现IEqualityComparer的模型对象与为实现IEqualityComparer的模型创建新类之间的区别_C#_Linq - Fatal编程技术网

C# 实现IEqualityComparer的模型对象与为实现IEqualityComparer的模型创建新类之间的区别

C# 实现IEqualityComparer的模型对象与为实现IEqualityComparer的模型创建新类之间的区别,c#,linq,C#,Linq,我有点困惑,什么时候我应该做以下任一项: public class Product : IEquatable<Comparer> { } 但是,如果我决定使用技术1,我仍然可以对linq执行相同的操作,或者只执行类似于var equal=ProductA==ProductB?的操作,当您的类型有一个默认的相等比较时,您希望实现它。如果要为给定类型实现多个自定义相等比较,可以让多个类实现并将它们传递给各种LINQ方法 例如,您可以有一个person类,它实现了IEquatable:

我有点困惑,什么时候我应该做以下任一项:

public class Product : IEquatable<Comparer> 
{
}
但是,如果我决定使用技术1,我仍然可以对linq执行相同的操作,或者只执行类似于
var equal=ProductA==ProductB

的操作,当您的类型有一个默认的相等比较时,您希望实现它。如果要为给定类型实现多个自定义相等比较,可以让多个类实现并将它们传递给各种LINQ方法

例如,您可以有一个person类,它实现了
IEquatable

公共类人员:IEquatable
{
公众人物(字符串名称,整数年龄)
{
名称=名称;
年龄=年龄;
}
公共字符串名称{get;}
公共整数{get;}
公共布尔等于(其他人)
{
if(ReferenceEquals(null,other))返回false;
if(ReferenceEquals(this,other))返回true;
返回字符串.Equals(Name,other.Name)&&Age==other.Age;
}
公共覆盖布尔等于(对象对象对象)
{
if(ReferenceEquals(null,obj))返回false;
if(ReferenceEquals(this,obj))返回true;
if(obj.GetType()!=this.GetType())返回false;
回报等于((人)obj);
}
公共覆盖int GetHashCode()
{
未经检查
{
返回((名称?.GetHashCode()??0)*397)^年龄;
}
}
公共静态布尔运算符==(左侧人员,右侧人员)
{
返回等于(左、右);
}
公共静态布尔运算符!=(左侧人员,右侧人员)
{
返回!等于(左,右);
}
}

但是现在您想要实现一个自定义比较器,它只基于人名执行相等性检查。您可以实现自定义的
IEqualityComparer

公共类ByNamePersonComparer:IEqualityComparer
{
公共布尔等于(人x,人y)
{
返回x.Name.Equals(y.Name,StringComparison.OrdinalIgnoreCase);
}
public int GetHashCode(Person obj)
{
返回obj.GetHashCode();
}
}

你是说
IEqualityComparer
IEqualityComparer
?@Lee不,我实际上是说让模型对象直接实现IEqualityComparer,而不是创建一个实现IEqualityComparer的附加类。例如,我想让我的产品类实现IEqualityComparer,但当linq函数要求使用比较器时,这对我没有好处。。实际上,我必须给它传递一个类,比如ProductComparer。
IEqualityComparer
用于为某些类型的
T
提供相等的“外部”定义,而
IEquatable
用于比较
T
项与接收器之间的相等性。如果您对您的类型有默认的相等概念,请实现
IEquatable
。在
Product
本身上实现
IEqualityComparer
是非常奇怪的,因为您需要创建一个新的
Product
实例来使用定义的equality/hashcode方法。我仍然不知道哪一个适合我。假设Product对象中有3个字段始终可用于比较产品。此外,我希望能够像上面的示例中那样与linq进行联合,以确保列表合并时没有重复:我应该使用哪一个?@BlakeRivell首先,请看我的示例,也许这会澄清问题。其次,如果您对
产品
相等性进行了一次比较,则可以在您的类型上实现
IEquatable
。LINQ将使用类型相等的底层实现来检查类型是否相等。我明白您在需要完全基于对象的特定属性进行自定义时是怎么说的,然后使用IEquality,否则,如果您只想比较使用IEquitable的整个对象,您会怎么说?或者通过单一比较,你是指一种财产还是多种财产?@BlakeRivell我不会说这是关于一种财产或所有财产的。我想说的更多的是关于默认的相等比较,如果同一对象类型有许多可能的相等,那么就有一个自定义实现。好吧,在我的例子中,我知道事实上我只有一组比较。那么我会使用公平权利吗?然后我想我的下一个问题是,我是让我的产品类直接实现它,还是创建另一个实现它的类,称为ProductComparer?假设我直接在我的产品类上实现了IEquitable,那么我如何在linq union语句中使用它呢?还有,为什么看起来IEquitable要比IEqualityComparer完成的工作要多得多?
public class ProductComparer : IEqualityComparer<Comparer> 
{
}
mergedProducts = products.Union(extraProducts, new ProductComparer()).ToList();
public class Person : IEquatable<Person>
{
    public Person(string name, int age)
    {
        Name = name;
        Age = age;
    }

    public string Name { get; }
    public int Age { get; }

    public bool Equals(Person other)
    {
        if (ReferenceEquals(null, other)) return false;
        if (ReferenceEquals(this, other)) return true;
        return string.Equals(Name, other.Name) && Age == other.Age;
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        if (ReferenceEquals(this, obj)) return true;
        if (obj.GetType() != this.GetType()) return false;
        return Equals((Person) obj);
    }

    public override int GetHashCode()
    {
        unchecked
        {
            return ((Name?.GetHashCode() ?? 0)*397) ^ Age;
        }
    }

    public static bool operator ==(Person left, Person right)
    {
        return Equals(left, right);
    }

    public static bool operator !=(Person left, Person right)
    {
        return !Equals(left, right);
    }
}
public class ByNamePersonComparer : IEqualityComparer<Person>
{
    public bool Equals(Person x, Person y)
    {
        return x.Name.Equals(y.Name, StringComparison.OrdinalIgnoreCase);
    }

    public int GetHashCode(Person obj)
    {
        return obj.GetHashCode();
    }
}