How to call a second-level base class method like base.base.GetHashCode()

前提是你 提交于 2019-12-17 16:42:14

问题


class A
{
    public override int GetHashCode()
    {
        return 1;
    }
}
class B : A
{
    public override int GetHashCode()
    {
        return ((object)this).GetHashCode();
    }
}

new B().GetHashCode()

this overflows the stack. How can I call Object.GetHashCode() from B.GetHashCode()?

edit: B now inherits from A.


回答1:


(edit - misread question)

If you want to get the original object.GetHashCode() version; you can't - at least, not unless A makes it available via something like:

protected int GetBaseHashCode() { return base.GetHashCode();}

(and have B call GetBaseHashCode()).

The reason it overflows is that GetHashCode is (obviously) virtual - it doesn't matter if you cast it to object; it still starts at the most-derived implementation in the actual object, i.e. B.GetHashCode() (hence the explosion).




回答2:


You can use RuntimeHelpers.GetHashCode(object) to get the original hash code of the object:

  class A
  {
    public override int GetHashCode()
    {
      Console.WriteLine("base hashcode is: " + base.GetHashCode());

      return 1;
    }
  }

  class Program
  {
    public static void Main(string[] args)
    {
      A a = new A();

      Console.WriteLine("A's hashcode: " + a.GetHashCode());

      Console.WriteLine("A's original hashcode: " + RuntimeHelpers.GetHashCode(a));
    }
  }

This produces the following result:

base hashcode is: 54267293
A's hashcode: 1
A's original hashcode: 54267293

If you take a look at RuntimeHelpers.GetHashCode(object) in Reflector, you'll see that it calls the internal static method object.InternalGetHashCode(object). If you'd like to know more, have a look at this question regarding the default implementation of GetHashCode.




回答3:


I'm using an external library and I wanted to call the base.base also (because of a bug in certain case). After some research I came across this page http://www.rsdn.ru/forum/dotnet/475911.aspx

It's quite simple: You define a delegate using the base class you want to call your method and set the object pointer to *this (or the object you want)

So, the important code is:

public delegate void MD();

public void Test() {
        // A is the base class you want to call the method.
        A a = new A();
        // Create your delegate using the method name "M" with the instance 'a' of the base class
        MD am = (MD)Delegate.CreateDelegate(typeof(MD), a, "M");
        // Get the target of the delegate and set it to your object (this in most case)
        am.GetType().BaseType.BaseType.GetField("_target", BindingFlags.Instance BindingFlags.NonPublic).SetValue(am, this);
        // call the method using the delegate.
        am();
    }



回答4:


If you can modify the code of the sub-sub class then you can implement the functionality of the sub-sub-method with a static method. This static (public) method has as first parameter an object of the class. That way you can call it from everywhere.

class A
{
    public static int CalcHashCode(A obj)
    {
        return 1;
    }

    public override int GetHashCode()
    {
        return CalcHashCode(this);
    }
}
class B : A
{
    public override int GetHashCode()
    {
        return A.CalcHashCode(this);
    }
}


来源:https://stackoverflow.com/questions/1006530/how-to-call-a-second-level-base-class-method-like-base-base-gethashcode

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!