字典ContainsKey似乎不能与string[] key一起工作



我试图有多个字符串键的数据结构。为此,我尝试创建一个带有string[]元素的Dictionary。但是ContainsKey似乎不像我期望的那样工作:

Dictionary<string[], int> aaa = new Dictionary<string[], int>();
int aaaCount = 0;
aaa.Add(new string[] { string1, string2 }, aaaCount++);
if (!aaa.ContainsKey(new string[] { string1, string2 }))
{
    aaa.Add(new string[] { string1, string2 }, aaaCount++);
}

我看到上面代码执行后aaa中有两个条目,而我期望只有一个。这是预期的行为吗?如何确保字典中没有重复的词条?

注意:我也尝试了同样的列表(列表和结果是相同的-包含方法并不真正与字符串[]一起工作)

如果您想使用string[]作为TKey,您应该将IEqualityComparer<string[]>传递给Dictionary的构造函数。因为字典使用TKey的标准比较,在string[]的情况下,它只是比较引用,因此string[]是引用类型。你必须自己实现IEqualityComparer。可以通过以下方式完成:

(实现相当幼稚,我提供它只是作为起点)

public class StringArrayComparer : IEqualityComparer<string[]>
{
    public bool Equals(string[] left, string[] right)
    {
        if (ReferenceEquals(left, right))
        {
            return true;
        }
        if ((left == null) || (right == null))
        {
            return false;
        }
        return left.SequenceEqual(right);
    }
    public int GetHashCode(string[] obj)
    {
        return obj.Aggregate(17, (res, item) => unchecked(res * 23 + item.GetHashCode()));
    }
}

您需要创建一个IEqualityComparer<string[]>并将其传递给字典的构造函数。

告诉字典如何比较键。
默认情况下,它通过引用比较它们。

因为数组是引用类型,也就是说,您正在检查引用 (identity)是否相等,而不是基于数组内的值是否相等。当您创建一个具有相同值的新数组时,数组本身仍然是两个不同的对象,因此ContainsKey返回false。

使用数组作为字典键有点…奇数。你想在这里描绘什么?也许有更好的办法

如果应用程序支持,最好将字符串数组合并为单个字符串。

在很多情况下,两条信息唯一地标识了集合中的一条记录,在这些情况下,我们使用一个不应该出现在任何一个字符串中的值(即Char(1))来连接这两个字符串。

由于添加的通常是类实例,因此我们让类指定键的生成,以便添加到集合的代码只需要检查单个属性(即CollectionKey)。

相关内容

  • 没有找到相关文章

最新更新