为什么2个委托实例返回相同的哈希码?

lep*_*pie 31 .net c# delegates hashcode

请考虑以下事项:

  var x =  new Action(() => { Console.Write("") ; });
  var y = new Action(() => { });
  var a = x.GetHashCode();
  var b = y.GetHashCode();
  Console.WriteLine(a == b);
  Console.WriteLine(x == y);
Run Code Online (Sandbox Code Playgroud)

这将打印:

True
False
Run Code Online (Sandbox Code Playgroud)

为什么哈希码相同?

这有点令人惊讶,并且会使代表的使用Dictionary速度与a List(也就是O(n)查找)一样慢.

更新:

问题是为什么.IOW谁做出这样一个(愚蠢的)决定?

一个更好的哈希码实现应该是:

return Method ^ Target == null ? 0 : Target.GetHashcode();
// where Method is IntPtr
Run Code Online (Sandbox Code Playgroud)

Ali*_*tad 10

简单!由于这里是GetHashCode (坐在基类上Delegate)的实现:

public override int GetHashCode()
{
    return base.GetType().GetHashCode();
}
Run Code Online (Sandbox Code Playgroud)

(坐在基类MulticastDelegate,其将上述调用):

public sealed override int GetHashCode()
{
    if (this.IsUnmanagedFunctionPtr())
    {
        return ValueType.GetHashCodeOfPtr(base._methodPtr);
    }
    object[] objArray = this._invocationList as object[];
    if (objArray == null)
    {
        return base.GetHashCode();
    }
    int num = 0;
    for (int i = 0; i < ((int) this._invocationCount); i++)
    {
        num = (num * 0x21) + objArray[i].GetHashCode();
    }
    return num;
}
Run Code Online (Sandbox Code Playgroud)

使用Reflector之类的工具,我们可以看到代码,看起来默认实现和我们上面看到的一样奇怪.

这里的类型值将是Action.因此上面的结果是正确的.

UPDATE

  • 老实说`return 42;`将*about*与`Delegate`实现一样有用(尽管`MulticastDelegate`看起来更好) (4认同)