C# 如何调用像base.base.GetHashCode()这样的二级基类方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1006530/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to call a second-level base class method like base.base.GetHashCode()
提问by usr
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()
?
这会溢出堆栈。我怎样才能Object.GetHashCode()
从打电话B.GetHashCode()
?
edit: B
now inherits from A
.
编辑:B
现在继承自A
.
采纳答案by Marc Gravell
(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:
如果您想获得原始object.GetHashCode()
版本;你不能 - 至少,除非A
通过以下方式使其可用:
protected int GetBaseHashCode() { return base.GetHashCode();}
(and have B
call GetBaseHashCode()
).
(并有B
电话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).
它溢出的原因GetHashCode
是(显然)是虚拟的 - 如果你将它转换为object
; 它仍然从实际对象中最衍生的实现开始,即B.GetHashCode()
(因此爆炸)。
回答by Igal Tabachnik
You can use RuntimeHelpers.GetHashCode(object)
to get the original hash code of the object:
您可以使用RuntimeHelpers.GetHashCode(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
基本哈希码为:54267293
A 的哈希码:1
A 的原始哈希码: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 questionregarding the default implementation of GetHashCode.
如果您查看RuntimeHelpers.GetHashCode(object)
Reflector 中的内容,您会看到它调用了内部静态方法object.InternalGetHashCode(object)
。如果您想了解更多信息,请查看有关 GetHashCode 的默认实现的这个问题。
回答by Sauleil
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
我正在使用外部库,我也想调用 base.base (因为在某些情况下存在错误)。经过一番研究,我发现了这个页面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)
这很简单:您使用要调用方法的基类定义一个委托,并将对象指针设置为 *this(或您想要的对象)
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();
}
回答by schoetbi
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);
}
}