标签: iequalitycomparer

如何在重写GetHashCode()的类型上使用Object.GetHashCode()

我有一个实现IEquatable <>的类A,使用它的字段(比如Ab和Ac)来实现/重写Equals()并覆盖GetHashCode(),并且99%的时候一切正常.A类是层次结构(B类,C类)的一部分,它们都从接口D继承; 它们都可以一起存储在字典中,因此当它们都带有自己的默认Equals()/ GetHashCode()时很方便.

然而,在构建AI时,有时需要做一些工作来获得Ab和Ac的值; 当发生这种情况时,我想存储对正在构建的实例的引用.在这种情况下,我不想使用A提供的默认Equals()/ GetHashCode()覆盖.因此,我正在考虑实现一个ReferenceEqualityComparer,这意味着强制使用Object的Equals()/ GetHashCode() :

    private class ReferenceEqualityComparer<T> : IEqualityComparer<T>
    {
        #region IEqualityComparer<T> Members
        public bool Equals(T x, T y)
        {
            return System.Object.ReferenceEquals(x, y);
        }

        public int GetHashCode(T obj)
        {
            // what goes here? I want to do something like System.Object.GetHashCode(obj);
        }
        #endregion
    }
Run Code Online (Sandbox Code Playgroud)

问题是,由于A重写了Object.GetHashCode(),我如何(在A之外)调用Object.GetHashCode()作为A的实例?

当然,一种方法是A不实现IEquatable <>并且始终为我创建的任何字典提供IEqualityComparer <>,但我希望得到不同的答案.

谢谢

c# iequatable iequalitycomparer gethashcode referenceequals

4
推荐指数
1
解决办法
1482
查看次数

List.Contains没有像希望的那样工作

如果我有一个类型的对象MyBull和一个List<MyBull> orig:

// Just an example
MyBull x = getMeTheObjectWithIdFromDB(9);

orig.add(x);

// Again same? data object
MyBull y = getMeTheObjectWithIdFromDB(9);
Run Code Online (Sandbox Code Playgroud)

为什么这是假的呢?

// This is false, even though all the properties
// of x and y are the same.
orig.Contains<MyBull>(y); 
Run Code Online (Sandbox Code Playgroud)

c# list iequalitycomparer

4
推荐指数
2
解决办法
6478
查看次数

为什么我们在 IEqualityComparer 中实现 GetHashCode?

我想List通过使用IEqualityComparer接口从C# 中获取不同的项目。但我不知道GetHashCode. 我已经实现了GetHashCodeEquals方法。以及如何调用Equals方法从具有用户定义数据类型的列表中获取不同的项目。

c# equals iequalitycomparer gethashcode

4
推荐指数
1
解决办法
2857
查看次数

实现IEqualityComparer <T>以比较任何类的任意属性(包括匿名)

我正在编写实现IEqualityComparer的这个整洁的类,因此我可以将任何匿名类型传递给它(或实际上任何具有属性的类型),它将通过比较类型的属性值自动比较类型.

public class CompareProperty<T> : IEqualityComparer<T>
    {
        private Type type;
        private PropertyInfo propInfo;
        private string _fieldName;

        public string fieldName
        {
            get;
            set;
        }

        public CompareProperty(string fieldName)
        {
            this.fieldName = fieldName;
        }

        public bool Equals<T>(T x, T y)
        {
            if (this.type == null)
            {
                type = x.GetType();
                propInfo = type.GetProperty(fieldName);
            }
            object objX = propInfo.GetValue(x, null);
            object objY = propInfo.GetValue(y, null);
            return objX.ToString() == objY.ToString();
        }
    }
Run Code Online (Sandbox Code Playgroud)

我认为这是一个很好的小助手功能,我可以多次使用.

为了使用它,我必须这样做:

var t = typeof(CompareProperty<>);
var g = t.MakeGenericType(infoType.GetType());
var c = g.GetConstructor(new …
Run Code Online (Sandbox Code Playgroud)

c# generics reflection equality iequalitycomparer

4
推荐指数
1
解决办法
5821
查看次数

LINQ Intersect,Union中的集合优先级,使用IEqualityComparer

如果我有两个类型为T的集合,以及一个比较其属性子集的IEqualityComparer,那么Intersect或Union的结果元素来自哪个集合?

我到目前为止进行的测试表明如下:

  • 来自col1 win的项目
  • 如果col1或col2本身包含重复项(由比较器定义),则第一个条目(在col1中,然后是col2)获胜.

我知道这不应该是一个问题,因为(根据定义)我应该将结果对象视为相等.我刚刚想到,使用带有自定义比较器的Union可能比等效的Join更整洁 - 尽管如果上述假设得到保证,这只适用.

    class DummyComparer : IEqualityComparer<Dummy>
    {
        public bool Equals(Dummy x, Dummy y)
        {
            return x.ID == y.ID;
        }

        public int GetHashCode(Dummy obj)
        {
            return obj.ID.GetHashCode();
        }
    }

    class Dummy
    {
        public int ID { get; set; }
        public string Name { get; set; }
    }

    [Test]
    public void UnionTest()
    {
        var comparer = new DummyComparer();

        var d1 = new Dummy { ID = 0, Name = "test0" };
        var d2 = new Dummy …
Run Code Online (Sandbox Code Playgroud)

c# linq union iequalitycomparer intersect

4
推荐指数
1
解决办法
733
查看次数

列表<T> .Except(List <T>)未按预期工作

我有两个相同类型的列表.

一个列表是从文件加载并转换为正确类型的反序列化json对象.

另一个是由相同类型的对象创建的列表.

当我这样做时,List2.Except(List1)我希望看到一切都List2没有List1

在这种情况下,List2将拥有所有的东西,List1而不是更多,所以我希望看到Enumerable<T>大小为0的结果,但我只是看到整个,List2好像比较从未发生过.

IEnumerable<Review> newReviews = reviews.Except(savedRvReviews, new ReviewComparer());
Run Code Online (Sandbox Code Playgroud)

我也试过使用EqualityComparer下面的代码:

public class ReviewComparer : IEqualityComparer<Review>
{
    public bool Equals(Review x, Review y)
    {
        return x.ReviewID == y.ReviewID;
    }

    public int GetHashCode(Review rv)
    {
        return EqualityComparer<Review>.Default.GetHashCode(rv);
    }
}
Run Code Online (Sandbox Code Playgroud)

并得到了相同的结果.

通过LINQ查询迭代List2和搜索List1,我得到0的预期结果.

foreach (Review s in reviews)
{
    var m = from k in savedRvReviews
    where k.ReviewID == s.ReviewID
    select k;

    if …
Run Code Online (Sandbox Code Playgroud)

c# iequalitycomparer except

4
推荐指数
1
解决办法
733
查看次数

C#/ LINQ比较两个列表和分配值的最快方法

我编写了一个代码,该代码基本上比较了C#中的两个列表。第一个列表包含以下属性:

  • 物品ID
  • 总浏览

第一个列表缺少TotalViews的值,因此我从第二个列表中为它们分配了这些道具:

  • 物品ID
  • HitCount //这是需要分配的TotalViews的属性

代码如下:

foreach (var item in parsedMerchantData)
{
    var itemInB = HitCountItemIDS.FirstOrDefault(x => x.ItemID == item.ItemID);
    if (itemInB != null)
    {
        if (itemInB.HitCount != -1)
        {
            item.TotalViews = itemInB.HitCount;
        }
        else
        {
            item.TotalViews = 0;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

是否有任何更有效的方式使用LINQ编写此代码或实现自定义比较器,该自定义比较器在有时包含100000个项目的较大列表上工作更快?

c# linq list iequalitycomparer c#-4.0

4
推荐指数
1
解决办法
853
查看次数

为什么我可以将对象与这些对象的IEnumerable进行比较而不是List?

我刚刚意识到我编写了我希望无效的代码(关于语法),但编译器接受了.

为了简洁起见,我重新创建了一个例子.给定类型:

private class MyType
{
}
Run Code Online (Sandbox Code Playgroud)

然后,我可以比较的一个实例MyTypeIEnumerable<MyType>:

var myCollection = new List<MyType> { };
var test = new MyType() == (IEnumerable<MyType>)myCollection;
Run Code Online (Sandbox Code Playgroud)

我很惊讶我能比较两种不同类型的物体.更有意思(至少对我有趣),如果我删除了演员,IEnumerable我无法比较它.为什么会这样?一个List工具,IEnumerable所以假设某种平等比较器在某个地方,我缺少(可能是错误的),为什么这也不可用List

c# ienumerable types casting iequalitycomparer

4
推荐指数
1
解决办法
189
查看次数

比较C#中的两个List <MyClass>

我有一个叫做的课

MyClass
Run Code Online (Sandbox Code Playgroud)

这个类继承IEquatable并实现等于我需要它的方式.(含义:当我在代码中单独比较两个MyClass tyupe对象时,它可以工作)

然后我创建两个List:

var ListA = new List<MyClass>();
var ListB = new List<MyClass>();
// Add distinct objects that are equal to one another to 
// ListA and ListB in such a way that they are not added in the same order.
Run Code Online (Sandbox Code Playgroud)

当我去比较ListA和ListB时,我应该得到真的吗?

ListA.Equals(ListB)==true; //???
Run Code Online (Sandbox Code Playgroud)

.net c# list iequatable iequalitycomparer

3
推荐指数
1
解决办法
431
查看次数

带有可为空字段的 EqualityComparer 的奇怪行为

假设有这个类:

public class Foo
{
    public int Id { get; set; }
    public int? NullableId { get; set; }

    public Foo(int id, int? nullableId)
    {
        Id = id;
        NullableId = nullableId;
    }
}
Run Code Online (Sandbox Code Playgroud)

我需要按照以下规则比较这些对象:

  1. 如果两个对象都有 NullableId 的值,那么我们比较 Id 和 NullableId
  2. 如果某些对象/它们都没有 NullableId,则忽略它并仅比较 Id。

为了实现它,我像这样覆盖了 Equals 和 GetHashCode:

public override bool Equals(object obj)
{
    var otherFoo = (Foo)obj;

    var equalityCondition = Id == otherFoo.Id;

    if (NullableId.HasValue && otherFoo.NullableId.HasValue)
        equalityCondition &= (NullableId== otherFoo.NullableId);

    return equalityCondition;
}

public override int GetHashCode()
{
    var …
Run Code Online (Sandbox Code Playgroud)

.net c# nullable iequalitycomparer

3
推荐指数
1
解决办法
180
查看次数