Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/meteor/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 非基于散列的集合集合,用于使用自定义相等比较器-C存储唯一对象#_C#_Collections_Set_Unique_Iequalitycomparer - Fatal编程技术网

C# 非基于散列的集合集合,用于使用自定义相等比较器-C存储唯一对象#

C# 非基于散列的集合集合,用于使用自定义相等比较器-C存储唯一对象#,c#,collections,set,unique,iequalitycomparer,C#,Collections,Set,Unique,Iequalitycomparer,我试图将(名称:string,值:long)对存储在一个集合中 公共类NameValuePair { 公共字符串名称; 公共长期价值; } public NameValuePairComparer comparer=新的NameValuePairComparer(); public HashSet nameValueSet=新HashSet(比较器); 如果两对具有相等的名称或相等的值,则它们是相等的-这在来自EqualityComparer的NameValuePairComparer重写Eq

我试图将(名称:string,值:long)对存储在一个集合中

公共类NameValuePair
{
公共字符串名称;
公共长期价值;
}
public NameValuePairComparer comparer=新的NameValuePairComparer();
public HashSet nameValueSet=新HashSet(比较器);
如果两对具有相等的名称或相等的值,则它们是相等的-这在来自EqualityComparer的NameValuePairComparer重写Equals方法中实现:

公共类名称ValuePairComparer:EqualityComparer
{
公共覆盖布尔等于(NameValuePair x,NameValuePair y)
{
返回(x.value==y.value)| |(x.name==y.name);
}
问题是:GetHashCode(NameValuePair obj)应该为两个Equals返回true的对象返回相同的值,因此对于给定的NameValuePair,GetHashCode()应该返回value.GetHashCode()或name.GetHashCode(),但要做到这一点,我们必须知道这两个对象对中的哪个字段是相等的:

public override int GetHashCode(NameValuePair obj)
{
/* ??? */
/*//使用对x的未知引用
if(obj.value==x.value)返回obj.value.GetHashCode();
else if(obj.name==x.name)返回obj.name.GetHashCode();
else返回base.GetHashCode(obj);
*/
}
}
但我们不知道这一点,这意味着我不能使用HashSet来存储这些对,也不能使用EqualityComparer

问:C#(.NET3.5)中没有基于哈希的set实现吗

Q:使用自定义相等比较器存储唯一的NameValuePairs的更好方法是什么

如果两对的名称或值相等,则两对相等

您根本无法使用这些标准正确实施。从
Equals
的文档中:

Equals方法是自反的、对称的和传递的。也就是说,如果用于将对象与自身进行比较,则返回true;如果对y和x为真,则对两个对象x和y为真;如果对x和y为真,对两个对象x和z为真,对y和z也为真

现在考虑配对:

x = { "A", 10 },
y = { "A", 20 },
z = { "B", 20 }
你是说,
x
y
必须相等,因为它们具有相同的名称,
y
z
必须相等,因为它们具有相同的值。这意味着(通过及物性,
x
z
应该相等

由于您无法正确地实现
IEqualityComparer
,因此您不应该期望依赖于该正确性的任何东西都能正常工作

我怀疑您会发现,如果您更详细地查看您的需求,它们要么真的需要两个集合(一个按名称,一个按值),要么就传递性而言没有意义


例如,假设您有一个具有您建议的特征的集合,并添加了上述三个元素。如果你按{x,y,z}的顺序添加它们,你会得到一个条目。如果你按{z,x,y}的顺序加上它们,你会得到两个。这是一种多么有用的集合?

@Jon:+1,说真的,你怎么认为这样的光速:)?传递性在这里并不重要。在您的示例中,如果集合中有x,我不能允许向其中添加“y”。如果集合中有“y”,我不能允许添加“z”或“x”。所以我认为使用自定义等式比较器的集合是最好的解决方案。如果我以{x,y,z}或{z,x,y}顺序添加它们,我将以{x,z}或{z,x}结束。@MariuszCeier:好的,那么你没有做替换:所以以{y,x,z}顺序添加它们,你只会得到一个条目。再说一次,这是一件好事吗?传递性对您可能并不重要,但它是
IEqualityComparer
中表示的相等关系的一个要求,因此您不应该实现该接口。考虑到您有一些奇怪的需求,您不应该期望它们在框架中得到满足。当以{y,x,z}顺序添加它们时,以单个条目结尾是一件好事,因为一对中的名称和值是1-1关系。考虑枚举类型——每个类型在该类型中都是名称-值对。这些条目在此类型中必须具有唯一的名称和唯一的值,因此当此类型中存在“y”时,“x”和“z”应返回错误(名称冲突或值冲突)。我不需要使用IEQualyExpor,我只需要一个集合集合,允许我定义相等比较器而不定义HashCode,比如STD::从C++设置。