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”。 我依靠这种行为调用base
GetHashCode
是一个实现的特殊情况,调用
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
调用隐藏的一个。更新答案。