我正在构建以下类来管理字典。
public class EnumDictionary<TKey, TValue>
{
private Dictionary<TKey, TValue> _Dict;
public EnumDictionary(Dictionary<TKey, TValue> Dict)
{
this._Dict = Dict;
}
public TKey GetValue(TValue value)
{
foreach (KeyValuePair<TKey, TValue> kvp in _Dict)
{
if (kvp.Value == value)
return kvp.Key;
}
throw new Exception("Undefined data type: " + value);
}
}
但我收到错误“运营商'=='无法应用于'TValue'和'TValue'类型的操作数。”
顺便说一句,我正在制作这个自定义集合是因为我的字典具有独特的价值,但我无法从字典中获取键值。
感谢任何帮助。谢谢。
答案 0 :(得分:5)
您是否尝试使用Equals
方法?
if (kvp.Value.Equals(value))
我认为这种限制是因为==
运算符不能用于所有类型。举例来说:
struct Test
{
public int Value;
}
鉴于上述结构,以下代码将无法编译:
Test a, b;
a = b = new Test();
bool areEqual = a == b; // Operator '==' cannot be applied to
// operands of type 'Test' and 'Test'
但是,所有类型都有Equals
方法,因此调用它将起作用:
Test a, b;
a = b = new Test();
bool areEqual = a.Equals(b);
答案 1 :(得分:3)
Fredrik is right;您需要使用Equals
,因为您不能假定能够对所有类型使用==
,因为没有为每种类型定义运算符。
根据您的情况,添加
也可能有意义where TValue : IEquatable<TValue>
作为类的泛型类型约束。这样做的原因是object.Equals
接受另一个object
作为参数,这意味着如果TValue
是值类型,则会将其装箱。另一方面,如果可以知道实施IEquatable<TValue>
,则可以将Equals
解析为IEquatable<TValue>.Equals
*,其中TValue
作为参数,因此赢得了'{1}} t要求将值类型装箱。
我可能也建议您重新考虑此类的内部结构。按照目前的情况,你根本不需要这个类,因为你可以轻松地向IDictionary<TKey, TValue>
添加一个扩展方法,通过对值的枚举来按值找到一个键。我要做的是存储两个字典:Dictionary<TKey, TValue>
和Dictionary<TValue, TKey>
,以便在O(1)中进行双向查找。
*顺便说一句,如果你很好奇,你不能使用IEquatable<T>
(或任何接口)来确保类型已经实现了{{1}运算符是运算符 static ,接口不能提供静态方法(因此不能提供运算符)。
答案 2 :(得分:0)
当你使用泛型比较时,我认为你应该实现一个(x)CompareTo(Y)或类似的类。如果我错了,请纠正我。
答案 3 :(得分:0)
在通用类型
上使用“where”条件class Dictionary<TKey,TVal>
where TKey: IComparable, IEnumerable
where TVal: MyI
{
public void Add(TKey key, TVal val)
{
}
}
来自http://msdn.microsoft.com/en-us/library/6b0scde8%28VS.80%29.aspx
答案 4 :(得分:0)
你可以使用if(kvp.Value.Equals(value))而不是==。
答案 5 :(得分:0)
不要创建新类。创建扩展方法:
public static class DictionaryHelper
{
public static TKey GetKeyFromValue<TKey, TValue>(this IDictionary<TKey, TValue> instance, TValue value)
{
foreach (var kvp in instance)
{
if (kvp.Value.Equals(value))
return kvp.Key;
}
return default(TKey);
}
}
public class Example
{
public static void Main(string[] argv)
{
Dictionary<string, string> test = new Dictionary<string, string> { { "Mykey", "MyValue" }, { "Key1", "Value2" } };
string key = test.GetKeyFromValue("MyValue");
}
}
答案 6 :(得分:0)
如果您希望这是通用的,那么您将希望可以配置相等的定义,就像它在键的字典中一样。
拥有IEqualityComparer<TValue>
类型的属性,该属性在构造函数中设置。
然后有一个构造函数的版本,使其成为默认的EqualityComparer<TValue>.Default
。这可以通过在相关类型上调用Equals
来实现。
public class EnumDictionary<TKey, TValue>
{
private Dictionary<TKey, TValue> _Dict;
private readonly IEqualityComparer<TValue> _cmp;
public EnumDictionary(Dictionary<TKey, TValue> Dict, IEqualityComparer<TValue> cmp)
{
this._Dict = Dict;
_cmp = cmp;
}
public EnumDictionary(Dictionary<TKey, TValue> Dict)
:this(Dict, IEqualityComparer<TValue>.Default){}
public TKey GetValue(TValue value)
{
foreach (KeyValuePair<TKey, TValue> kvp in _Dict)
{
if (cmp.Equals(kvp.Value, value))
return kvp.Key;
}
throw new Exception("Undefined data type: " + value);
}
}