假设我们有这个课程:
public class Moo { string _value; public Moo(string value) { this._value = value; } public static implicit operator string(Moo x) { return x._value; } public static implicit operator Moo(string x) { return new Moo(x); } public override bool Equals(object obj) { if (obj is string) return this._value == obj.ToString(); else if (obj is Moo) return this._value == ((Moo)obj)._value; return base.Equals(obj); } public override int GetHashCode() { return _value.GetHashCode(); } }
如果我将这种类型的对象添加到Hashtable,那么我可以使用相同的字符串找到该对象.
但是如果Hashtable包含字符串而不是对象,则在传递对象时无法找到它.
Moo moo = new Moo("abc"); bool result1 = moo == "abc"; //true bool result1a = moo.Equals("abc"); //true bool result2 = "abc" == moo; //true bool result2a = "abc".Equals(moo); //true bool result2b = ((object)"abc").Equals(moo); //false Hashtable hash = new Hashtable(); hash[moo] = 100; object result3 = hash[moo]; //100 object result4 = hash["abc"]; //100 hash = new Hashtable(); hash["abc"] = 100; object result5 = hash[moo]; //null!!!! object result6 = hash["abc"]; //100
我已经尝试重写operator ==并且它没有任何区别.
是否可以通过这种方式在Hashtable中使用隐式转换?
解决方法
首先,为什么使用哈希表而不是通用词典<,>?
无论如何,你的问题是哈希表调用((object)“abc”).当然,等于(moo),返回false.您可以通过使用IEqualityComparer参数将自己的IEqualityComparer实现传递给其中一个HashTable构造函数来覆盖该行为.
正如您所指出的那样,您正试图避免修改遗留代码,因此您可能无法将现有哈希表替换为具有自定义IEqualityComparer的哈希表.如果这是真的,那么我认为答案是你不能做你想做的事.
既然你正在开发这个“moo”类,我想你可以控制将moo类传递给哈希表的索引器的代码.如果这是真的,你可以在你传递给索引器的对象上调用ToString(),当然,在Moo中覆盖ToString.