0

我正在使用 ConcurrentDictionary ,关键是由具有公共属性的类组成。

在玩弄了来自(HashCode on decimal with IEqualityComparer in a ConcurrentDictionary)的代码之后,我想找到一个解决方案,所以我不必为我创建的每个属性类实现具有接口 IEqualityComparer 的类。

我已经创建了一个基类,可以检查是否设置了所有公共属性(或者至少不是默认值)。所以,我想,让我们尝试一下,将 IEqualityComparer 类添加到基类中。

到目前为止,我有这个并且它确实有效。

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;

    private void SomeMethod()
{
    ConcurrentDictionary<TwoUintsOneStringsKeyInfo,int> test = new  ConcurrentDictionary<TwoUintsOneStringsKeyInfo, int>(new    TwoUintsOneStringsKeyInfo.EqualityComparerElevenUintsKeyInfo());
    test.TryAdd(new TwoUintsOneStringsKeyInfo { IdOne = 1, IdTwo = 2, mySTring = "Hi" }, 1);
    test.TryAdd(new TwoUintsOneStringsKeyInfo { IdOne = 2, IdTwo = 3, mySTring = "hello" }, 2);
    test.TryAdd(new TwoUintsOneStringsKeyInfo { IdOne = 3, IdTwo = 4 }, 3);

    int result;
    test.TryGetValue(new TwoUintsOneStringsKeyInfo { IdOne = 2, IdTwo = 3, mySTring = "hello" }, out result);
}


    public class PropertyBaseClass
{
    public bool AllPublicProperiesAreSet()
    {
        //some logic (removed for now. Not important for the question)

    }

    public class EqualityComparerElevenUintsKeyInfo : IEqualityComparer<TwoUintsOneStringsKeyInfo>
    {
        public int GetHashCode(TwoUintsOneStringsKeyInfo obj)
        {
            int hash = 17;
            System.Reflection.PropertyInfo[] properties = obj.GetType().GetProperties().OrderBy(x=>x.Name).ToArray();
            int counter=0;
            foreach(System.Reflection.PropertyInfo p in properties)
            {
                counter++;
                var value = p.GetValue(obj);
                hash = hash * 23 + (value == null ? (Math.Pow(1.111, counter)).GetHashCode() : value.GetHashCode());
            }

            return hash;
        }

        public bool Equals(TwoUintsOneStringsKeyInfo x, TwoUintsOneStringsKeyInfo y)
        {
            return x.IdOne == y.IdOne &&
                    x.IdTwo == y.IdTwo;
        }
    }
}

public class TwoUintsOneStringsKeyInfo : PropertyBaseClass
{
    public uint IdOne { get; set; }
    public uint IdTwo { get; set; }
    public string mySTring { get; set; }
}

我只用三个属性做了这个例子。通常有越来越多不同的类型,我只是不想为每个属性类在 concurrentDictionary 中使用自定义类。

事情是(当然),现在的方式,它只适用于 TwoUintsOneStringsKeyInfo 类型的属性类,因为我必须在实现 IEqualityComparer<> 时指定它。

有什么方法可以将 EqualityComparerElevenUintsKeyInfo 类实现到基类并使其灵活,使 EqualityComparerElevenUintsKeyInfo 检查哪个类实现了 EqualityComparerElevenUintsKeyInfo 并将该类用作 IEqualityComparer、GetHashCode 和 Equals 的参数(如果可以这样做的话我想要,我当然也会更改 Equals 方法。

建议?

亲切的问候,

马蒂斯

4

0 回答 0