所以,我有一个词典,我需要检查其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
语句进行检查。关于我怎么能这样做的任何提示?
答案 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>
界面及其Equals
和GetHashCode
方法。
现在,问题是,字典根据其哈希码(由GetHashCode
提供)将您的项目存储在存储桶中。
您必须确保两个Symbols
返回相同的哈希码。
您对哈希的计算不应该依赖于OPC
或Type
属性:对象的哈希码必须在存储在哈希映射中时保持不变(例如字典)。
并且因为这两个属性可以更改,所以依赖于它们的哈希码也可以更改。这会打破字典的用处。
实施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类的Equals
和GetHashCode
方法就足够了吗?
当您覆盖Equals
和GetHashCode
时,您正在更改对象确定它是否等于另一个的方式。还有一个注意事项,如果使用==
运算符比较对象,它将不会具有与Equals相同的行为,除非您也覆盖运算符。
这样做改变了单个类的行为,如果你需要其他类的相同逻辑怎么办?如果您需要“通用比较”。这就是为什么你有IEqualityComparer
。