C# 为什么是';基数';反对我的具体类型?
这似乎是一个非常简单的问题,但很明显我遗漏了一些东西。 我做了一个测试:C# 为什么是';基数';反对我的具体类型?,c#,gethashcode,C#,Gethashcode,这似乎是一个非常简单的问题,但很明显我遗漏了一些东西。 我做了一个测试: class A { public override int GetHashCode() { Console.WriteLine(base.GetType().Name); return 0; } } 我本想找到“object”,但我找到了“A”。 我依靠这种行为调用baseGetHashCode是一个实现的特殊情况,调用base.GetHashCode(),我希望调
class A
{
public override int GetHashCode()
{
Console.WriteLine(base.GetType().Name);
return 0;
}
}
我本想找到“object”,但我找到了“A”。
我依靠这种行为调用baseGetHashCode
是一个实现的特殊情况,调用base.GetHashCode()
,我希望调用对象
实现
有什么问题吗?
base。
符号更改了被重写的virtual
方法调用的方法(如示例中的GetHashCode
,base.GetHashCode()
调用object.GetHashCode
,this.GetHashCode()
调用A.GetHashCode()
)<代码>基类。也可用于隐藏基类的方法,但本示例中的情况并非如此
由于GetType
不是虚拟的,没有隐藏,因此调用this.GetType()
和base.GetType()
的行为相同,并调用对象。GetType
返回在GetType()
中指定的“当前实例的确切运行时类型”,始终返回当前类型,即使在base
上调用。要获取基类型,可以执行以下操作:
class A
{
public override int GetHashCode()
{
Console.WriteLine(this.GetType().BaseType.Name);
return 0;
}
}
顺便说一句,base.GetHashCode()按预期工作。如果您在
A
中调用它,它将执行对象
实现。Equalsk的注释和post()是您需要知道的,但我将进一步告诉您为什么要这样做
给定的A类
仅继承自系统对象
,
给定类B
和类C
是类A
的子类:
在类B或C中,base.GetType().Name
将是A。您希望这样,因为它是在它们从A继承的子类中定义的
在A类中,您仍然可以得到A。为什么您不想要对象
答案很简单。假设我写了这样一个方法:
public static void DoStuff(A input)
{
}
我可以发送DoStuff(input)
,其中input
为A类、B类或C类。这是因为它们的base
类型为A。这是可取的。我们不希望隐式地(并且令人困惑地)将类A从接受其派生的方法中排除;如果我们这样做了,我们希望A是一个不可实例化的接口
将System.Object
视为祖先。如果有人问你来自哪里,你不会回答“美索不达米亚的进化”,你通常只会回答与你的存在相关的血统。对象
类本质上是原始的软泥,因此除非您试图告诉它应该接受作为参数传递的任何内容,或者不确定要处理的对象类型,否则您不会引用它
最后一种情况的一个例子是:
public void DoStuffAgain(object x)
{
Messagebox.Show(x.GetType().Name);
}
从理论上讲,所有进入管道的东西都是对象
。相反,你可以通过你的“A”类,你想知道“A”,因为你通过了它。即使x的类型为对象
,也是如此
BaseType
(属性)将返回类的基,如其他答案中所述。但是,这不会导致您找到对象
,除非该类没有显式地从其他对象继承 你在这里混淆了两件截然不同的事情。一个是调用什么方法实现,另一个是对象的运行时类型
object.GetType()
在object
中实现,它将始终返回所调用实例的运行时类型
现在,当您从没有实现Foo
而是从基类型(您的案例)继承它的任何给定类调用方法Foo
时,base.Foo
或Foo
本质上是一样的,因为唯一存在的Foo
是base.Foo
但是,如果类实现了自己的Foo
,那么它将重写虚拟方法或隐藏非虚拟方法,调用的方法将不同。不要被其他答案弄糊涂,这些答案指出您看到的行为是由于GetType
不是虚拟的,这是不正确的
class A { int Foo() => 1;}
class B { }
class C { new int Foo() => 2; }
从
B
中调用Foo
或base.Foo
是相同的,从C
中调用它是不同的;前者将返回2
后者1
object
的GetType()
实现旨在返回实际的运行时对象类型,这就是它在这里所做的。GetType()
将始终返回它所调用的实例的具体、实际的子类<在本例中,code>base.GetHashCode()应该调用对象.GetHashCode()
方法。编辑:所以,我不完全确定您面临的问题是什么,或者为什么它不调用该方法的对象
实现。也许您需要显示正在使用的实际代码,或者更好地澄清您的问题。请注意,Object.GetType()
不是虚拟方法。通过base
调用它不会做任何特殊的事情(不像base.GetHashCode()
,后者会)。如果要在运行时获取基类型,请使用this.GetType().BaseType
。(如果从继承层次结构的更深层调用,则不必是类派生的编译时类型。)您只需要new object().GetType().Name
或typeof(object.Name
@jeroenmoster它是虚拟的还是非虚拟的这一事实无关紧要<如果类型隐藏对象,则code>base.GetType()将返回不同的结果。GetType()。如果GetType
隐藏,两者仍将返回相同的结果?@是的,您是对的-您可以使用base
调用隐藏的一个。更新答案。