将对象隐式转换为字符串,以便在Hashtable中使用

dem*_*key 6 c# hashtable implicit-conversion

假设我们有这个课程:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我将这种类型的对象添加到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
Run Code Online (Sandbox Code Playgroud)

我已经尝试重写operator ==并且它没有任何区别.
是否可以通过这种方式在Hashtable中使用隐式转换?

pho*_*oog 5

首先,为什么使用散列表而不是泛型Dictionary<,>

无论如何,你的问题是哈希表正在调用((object)"abc").Equals(moo),当然它返回false.您可以通过使用参数将自己的实现传递IEqualityComparer给其中一个HashTable构造函数来覆盖该行为IEqualityComparer.

正如您所指出的那样,您正试图避免修改遗留代码,因此您可能无法将现有哈希表替换为具有自定义IEqualityComparer的哈希表.如果这是真的,那么我认为答案是你不能做你想做的事.

既然你正在开发这个"moo"类,我想你可以控制将moo类传递给哈希表的索引器的代码.如果这是真的,你可以只叫ToString()你传递给索引器的对象,当然,覆盖ToStringMoo.

  • @demoncodemonkey:`"abc".Equals(moo)`只返回true,因为编译器正在执行运算符重载 - 它在编译时*知道*.尝试`((object)"abc").Equals(moo)`看看Hashtable会做什么. (3认同)
  • `"abc".Equals(moo)`对我来说是真的.如果你将`moo`分配给```实例,那么 - ""abc".Equals(mooObj)`返回false. (2认同)
  • 你必须使用`IEqualityComparer <T>`(或者如果你坚持使用遗留集合,那么它是非通用的等价物).你不能使用`Equals`,因为它必须是**对称的,否则你在使用基于相等的集合时会得到未定义的行为. (2认同)