检查Dictionary是否在其任何键中都有值

时间:2013-11-29 14:24:01

标签: c# dictionary contains

所以,我有一个词典,我需要检查其Keys中是否存在某个Value。作为价值,我使用这个类:

class Symbols
{
    public bool OPC { get; set; }

    public string Type { get; set; }
}

而且,我正在为字典分配以下键和值:

public static Dictionary<string, Symbols> SymbolDictionary = new Dictionary<string, Symbols>(StringComparer.CurrentCultureIgnoreCase);

Symbols symbol = new Symbols();

symbol.OPC = false;
symbol.Type = "Type";

SymbolDictionary.Add(Key,symbol);

如果我检查SymbolDictionary[Key].symbol.OPC(或.symbol.Type),我会得到完全正确的值。但是当我尝试在if中执行此操作时,它永远不会返回true

if (SymbolDictionary.ContainsValue(symbol)) Console.WriteLine("Something");

因为它永远找不到值的匹配,即使我添加了值并立即使用if语句进行检查。关于我怎么能这样做的任何提示?

5 个答案:

答案 0 :(得分:4)

那是因为你没有为你的班级提供任何比较方法。

  

Default属性检查类型T是否实现了   System.IEquatable接口,如果是,则返回一个   使用该实现的EqualityComparer。否则,它   返回使用覆盖的EqualityComparer   由T。

提供的Object.Equals和Object.GetHashCode

进一步阅读:

答案 1 :(得分:3)

TL; DR:您的Symbols类必须实现IEquatable<Symbols>才能使比较按“预期”工作,或者您必须安装自定义相等比较器when constructing the dictionary

ContainsValue方法使用EqualityComparer<T>.Default作为将指定值与字典中的值进行比较以确定相等性的方法。如果类T未实现IEquatable<T>,则默认的相等比较器使用引用相等性;这意味着这种比较不起作用:

Symbols symbol1 = new Symbols();    
Symbols symbol2 = new Symbols();    
SymbolDictionary.Add("key", symbol1);
if (SymbolDictionary.ContainsValue(symbol2)) ... // false!

首先,您必须在符号的上下文中确定“相等”的含义,然后相应地实现相等比较。 确保在实施时阅读并注意IEquatable<T>文档中的评论!

答案 2 :(得分:2)

您提供的代码运作正常。 你实际上在做什么,可能与你发布的内容略有不同。 你可能正在创建一个新的Symbols对象,对吗?这会失败:

        Symbols symbol = new Symbols();
        symbol.OPC = false;
        symbol.Type = "Type";
        SymbolDictionary.Add("key", symbol);

        //create new instance
        symbol = new Symbols();
        symbol.OPC = false;
        symbol.Type = "Type";
        Debug.WriteLine(SymbolDictionary.ContainsValue(symbol));

您应该实施IEqualityComparer<Symbols>界面及其EqualsGetHashCode方法。

现在,问题是,字典根据其哈希码(由GetHashCode提供)将您的项目存储在存储桶中。 您必须确保两个Symbols返回相同的哈希码。

您对哈希的计算不应该依赖于OPCType属性:对象的哈希码必须在存储在哈希映射中时保持不变(例如字典)。 并且因为这两个属性可以更改,所以依赖于它们的哈希码也可以更改。这会打破字典的用处。

实施GetHashCode的准则和规则:http://ericlippert.com/2011/02/28/guidelines-and-rules-for-gethashcode/

答案 3 :(得分:1)

您可以阅读:http://msdn.microsoft.com/en-us/library/a63811ah(v=vs.110).aspx

此metod使用默认的相等比较器,因此您必须实现IEquatable:

class Symbols : IEquatable<Symbols>
{
    public bool OPC { get; set; }

    public string Type { get; set; }

    public bool Equals(Symbols other)
    {
    //here your comparision code
    }
}

答案 4 :(得分:0)

除了这个主题之外,人们可能会问,只要覆盖Symbol类的EqualsGetHashCode方法就足够了吗?

当您覆盖EqualsGetHashCode时,您正在更改对象确定它是否等于另一个的方式。还有一个注意事项,如果使用==运算符比较对象,它将不会具有与Equals相同的行为,除非您也覆盖运算符。

这样做改变了单个类的行为,如果你需要其他类的相同逻辑怎么办?如果您需要“通用比较”。这就是为什么你有IEqualityComparer