私は ConcurrentDictionary を使用していますが、キーはパブリック プロパティを持つクラスで構成されています。
( ConcurrentDictionary の IEqualityComparer を使用した 10 進数の HashCode )のコードをいじった後、解決策を見つけたかったので、作成するすべてのプロパティ クラスに対してインターフェイス 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; }
}
この例は、3 つのプロパティだけで作成しました。通常、より多くの異なるタイプがあり、すべてのプロパティ クラスの concurrentDictionary で使用されるカスタム クラスを作成したくありません。
(もちろん) 現状では、TwoUintsOneStringsKeyInfo 型のプロパティ クラスに対してのみ機能します。これは、IEqualityComparer<> を実装するときに指定する必要があるためです。
EqualityComparerElevenUintsKeyInfo クラスを基本クラスに実装し、EqualityComparerElevenUintsKeyInfo がどのクラスが EqualityComparerElevenUintsKeyInfo を実装しているかをチェックし、そのクラスを IEqualityComparer、GetHashCode、および Equals のパラメーターとして使用する方法で柔軟にする方法はありますか?もちろん、Equals メソッドも変更します。
提案?
敬具、
マティス