我有很多实体需要在他们之间共享数据。两个实体都将从此词典中请求值。
public class Key {
public string nameA;
public string nameB;
}
public class SharedValue {
public int id;
}
private Dictionary<Key, SharedValue> relation = new Dictionary<Key, SharedValue>();
然后加入字典。
relation.Add(new Key(){ nameA = "User1", nameB = "User2" }, new SharedValue(){ id = -11 });
最后,我希望无论nameA或nameB的顺序如何,我都可以获得共享的SharedValue。
relation[new Key(){ nameA = "User1", nameB = "User2" }].id // Get -11
relation[new Key(){ nameA = "User2", nameB = "User1" }].id // Get -11
答案 0 :(得分:1)
为您的密钥类定义Equals
和GeyHashCode
方法:
public class Key
{
public string nameA;
public string nameB;
public override bool Equals(object obj)
{
return base.Equals(obj as Key);
}
protected bool Equals(Key other)
{
return string.Equals(nameA, other.nameA) && string.Equals(nameB, other.nameB) ||
string.Equals(nameA, other.nameB) && string.Equals(nameB, other.nameA);
}
public override int GetHashCode()
{
return (nameA?.GetHashCode() ^ nameB?.GetHashCode()) ?? 0;
}
}
答案 1 :(得分:1)
您可以提供一个cutom IEqualityComparer<Key>
,您可以将其用于字典构造函数(以及许多LINQ方法):
public class UnorderedKeyComparer : IEqualityComparer<Key>
{
public bool Equals(Key x, Key y)
{
if (object.ReferenceEquals(x, y))
return true;
if (x == null || y == null)
return false;
if (string.Equals(x.NameA, y.NameA) && string.Equals(x.NameB, y.NameB))
return true;
if (string.Equals(x.NameA, y.NameB) && string.Equals(x.NameB, y.NameA))
return true;
return false;
}
public int GetHashCode(Key obj)
{
return (obj?.NameA?.GetHashCode() ?? int.MinValue) ^ (obj?.NameB?.GetHashCode() ?? int.MinValue);
}
}
因此,在这种情况下,您只需要使用UnorderedKeyComparer
初始化字典:
Dictionary<Key, SharedValue> Relation = new Dictionary<Key, SharedValue>(new UnorderedKeyComparer());
顺便说一句,我无法抗拒修复你的命名问题。
答案 2 :(得分:0)
您有很多选择,例如:
IEqualityComparer<YourKey>
并传递一个实例
class实现IEqualityComparer<YourKey>
到构造函数
字典IEquatable<T>
。这是Option 2
:
public class Key:IEquatable<Key> {
public string nameA;
public string nameB;
public bool Equals(Key other)
{
if(other == null)
return false;
if(ReferenceEquals(this,other))
return true;
return (string.Equals(this.nameA,other.nameA) && string.Equals(this.nameB,other.nameB))
|| (string.Equals(this.nameA,other.nameB) && string.Equals(this.nameB,other.nameA));
}
public override bool Equals(object obj){
if(obj == null)
return false;
if(ReferenceEquals(obj,this))
return true;
return Equals((Key)obj);
}
public override int GetHashCode(){
return (nameA?.GetHashCode() ^ nameB?.GetHashCode()) ?? 0;
}
}
测试:
private static Dictionary<Key, SharedValue> relation = new Dictionary<Key, SharedValue>();
static void Main(string[] args)
{
relation.Add(new Key{nameA="a",nameB="b"},new SharedValue{id=1});
if(relation.ContainsKey(new Key{nameA="a",nameB="b"})){
Console.WriteLine("YES");
}
if(relation.ContainsKey(new Key{nameA="b",nameB="a"})){
Console.WriteLine("YES");
}
else Console.WriteLine("NO");
}
输出:
YES
YES