Mar*_*ier 2 c# collections unique set iequalitycomparer
我正在尝试在一个集合中存储(名称:字符串,值:长)对.
public class NameValuePair
{
public string name;
public long value;
}
public NameValuePairComparer comparer = new NameValuePairComparer();
public HashSet<NameValuePair> nameValueSet = new HashSet<NameValuePair>(comparer);
Run Code Online (Sandbox Code Playgroud)
如果它们具有相同的名称或相等的值,则两对相等 - 这是在NameValuePairComparer中实现,从EqualityComparer中重写Equals方法:
public class NameValuePairComparer : EqualityComparer<NameValuePair>
{
public override bool Equals(NameValuePair x, NameValuePair y)
{
return (x.value == y.value) || (x.name == y.name);
}
Run Code Online (Sandbox Code Playgroud)
问题是:GetHashCode(NameValuePair obj)应为两个对象返回相同的值,其中Equals返回true,因此对于给定的NameValuePair,GetHashCode()应返回value.GetHashCode()或name.GetHashCode(),但要执行此操作我们必须知道两对中的哪个字段相等:
public override int GetHashCode(NameValuePair obj)
{
/* ??? */
/* // Using unknown reference to x
if (obj.value == x.value) return obj.value.GetHashCode();
else if (obj.name == x.name) return obj.name.GetHashCode();
else return base.GetHashCode(obj);
*/
}
}
Run Code Online (Sandbox Code Playgroud)
但是我们无法知道这一点,这意味着我不能使用HashSet来存储这些对,也不能使用EqualityComparer.
问:在C#(.net 3.5)中是否存在基于非哈希的set实现?
问:使用自定义相等比较器存储唯一的NameValuePairs有什么更好的方法?
如果它们具有相同的名称或相等的值,则两对相等
您从根本上无法IEqualityComparer<T>正确使用这些条件.来自以下文件Equals:
Equals方法是自反,对称和传递的.也就是说,如果用于将对象与自身进行比较,则返回true; 如果y和x为真,则对于两个对象x和y为true; 如果x和y为真,则对于两个对象x和z都为true,对于y和z也为true.
现在考虑对:
x = { "A", 10 },
y = { "A", 20 },
z = { "B", 20 }
Run Code Online (Sandbox Code Playgroud)
你说的是,x并且y必须相同,因为它们具有相同的名称,y并且z必须相同,因为它们具有相同的值.这意味着(通过传递性)x并且z应该是平等的.
由于您无法IEqualityComparer<T>正确实现,因此您不应期望任何依赖于该正确性的工作.
我怀疑你会发现如果你更详细地看一下你的要求,他们要么真的要求两个集合(一个是名字,一个是按值),要么根据传递性没有意义.
例如,假设您有一个具有您建议的特征的集合,并添加上面的三个元素.如果按照{x,y,z}的顺序添加它们,您最终会得到一个条目.如果按照{z,x,y}的顺序添加它们,最终会得到两个.这怎么样有用?