[英]Multiple inheritance problem in C#
在我阅读帖子时,我想到了这个问题为什么C#不支持多重继承? 来自MSDN博客 。
首先看下面的代码:
using System;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApplication1
{
class A
{
int num;
public A()
{
num = 0;
}
public A(int x)
{
num = x;
}
public override int GetHashCode()
{
return num + base.GetHashCode();
}
}
class B : A
{
int num;
public B()
{
num = 0;
}
public B(int x)
{
num = x;
}
public override int GetHashCode()
{
return num + base.GetHashCode();
}
}
class Program
{
static void Main(string[] args)
{
A a = new A();
B b = new B();
Console.Write(a.GetHashCode() + " " + b.GetHashCode());
Console.Read();
}
}
}
Object
类是所有类的最终基类 。 所以它是我程序中A
和B
的基类,也是A
作为B
的基类。 所以B
现在有两个基类,一个是A
,另一个是Object
。 我覆盖一个方法GetHashCode()
的Object
类中的类A
和B
这两者。 但是在B
类中, base.GetHashCode()
方法返回类A
的GetHashCode()
方法的返回值。 但我想从Object
类中获取此值。 我怎么能得到它?
B
只有一个基类,即A
A
有一个基类,那就是object
。 没有多重继承; object
只能由尚未从其他东西继承的类继承。
如果你仍然认为你需要调用object.GetHashCode()
,那么在如何调用(非虚拟)虚拟方法的原始实现的问题中有一个非常hacky的解决方法吗? 。
您可以在A类中编写一个受保护的实例方法,该方法从Object
公开GetHashCode()
。 然后在B类中调用该受保护的方法。
没有B类只有一个基类,A类。
要理解,A级真的应该写成:
class A : Object
但由于这是必需的,因此可以不予考虑。
是的,这根本不涉及多重继承(顺便说一句,我错过了私有继承而不是多重继承)。 这个问题也是一个非常可怕的想法。
如果你控制了A级,那么罚款:
class A
{
/*elide the stuff you already have*/
protected int GetBaseHashCode()
{
return base.GetHashCode();
}
}
class A : B
{
/*elide stuff already in example*/
public override int GetHashCode()
{
return num + GetBaseHashCode();
}
}
如果你不:
public class B : A
{
private static readonly DynamicMethod GRANDPARENT_GET_HASH_CODE;
static B()
{
MethodInfo gpGHC = typeof(object).GetMethod("GetHashCode", BindingFlags.Public | BindingFlags.Instance);
GRANDPARENT_GET_HASH_CODE = new DynamicMethod("grandParentGHC", typeof(int), new Type[] { typeof(object) }, typeof(object));
ILGenerator il = GRANDPARENT_GET_HASH_CODE.GetILGenerator();
il.Emit(OpCodes.Ldarg, 0);
il.EmitCall(OpCodes.Call, gpGHC, null);
il.Emit(OpCodes.Ret);
}
private int num;
public B()
{
num = 0;
}
public B(int x)
{
num = x;
}
public override int GetHashCode()
{
return num + (int)GRANDPARENT_GET_HASH_CODE.Invoke(null, new object[]{this});
}
}
坦率地说,我会把这些代码放在“让我们再也不说它”的范畴内。 我认为这与一些更一般的原则有关,因为这里的哈希码无论如何都是无用的,但我不确定那个更一般的原则是什么。 当然,当某些东西被隐藏起来导致我们想要得到的类时,它有时会很烦人,但是当相反的情况发生时会更糟。
回到VB6时代,那种语言的编码人员往往不得不做一些令人讨厌的事情,包括获取用于虚拟调用查找的v表的内存地址,改变内存保护,然后手动调整存储在那里的字节,因为在“保护”用户免受实现细节的影响时,他们将一些重要的东西远离它们(如果没有这种技术,你就无法创建枚举器,只能将其传递给其他对象)。
谢天谢地,我们在C#中没有受到“保护”。 如果我必须像上面给出的一个真实项目的答案那样编写代码,那么我晚上需要喝几杯才能恢复。
获取基础Object
类的哈希与方法的目的无关。 GetHashCode()
是根据对象的特定类型和状态生成唯一(尽可能)的标识值。
GetHashCode()
方法使用默认的散列算法,可用于确定实例标识和唯一性,但不保证唯一性。 默认算法使用对象的状态来生成哈希。
更多信息: http : //msdn.microsoft.com/en-us/library/system.object.gethashcode.aspx
我担心你将正常继承与多重继承混合在一起。 多继承meand你有3个类A是B和C的子类,但B既不是C的子类,也不是C的子类。
正常继承确实允许链接,就像A是B的子类,它是C的子类。如果你调用方法,它可以遍历类并检查调用哪个方法(实际上它不会逐个检查类)。 这里B是A的子类,它是Object的子类。 对象碰巧有(虚拟)方法GetHashCode
- 通过在子类中重载它。 隐藏了Object方法,并且(不带技巧)无法使用。
您应该考虑调用Object.GetHashCode()的替代方法。 这就是为什么( 来自MSDN Library ):
GetHashCode方法的默认实现不保证不同对象的唯一返回值。 此外,.NET Framework不保证GetHashCode方法的默认实现,并且它返回的值在不同版本的.NET Framework之间是相同的。 因此,此方法的默认实现不得用作散列目的的唯一对象标识符。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.