这似乎是一个非常简单的问题,但显然我错过了一些东西。 我做了一个测试:
GetHashCode
我期待找到'对象',但我发现'A'。
我依靠这种行为来调用基类base.GetHashCode()
是带有实现的特殊情况,调用object
并且我期望调用weights = tf.Variable(tf.truncated_normal([2,3]))
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print('Weights:')
print(sess.run(weights))
print("{0:2f}".format(sess.run(weights)))
实现。
怎么了?
答案 0 :(得分:2)
base.
符号更改为被覆盖的virtual
方法调用的方法(例如样本中的GetHashCode
- base.GetHashCode()
调用object.GetHashCode
,this.GetHashCode()
来电A.GetHashCode()
)。 base.
也可以用于隐藏基类的方法,但在此示例中并非如此。
由于GetType
不是虚拟的,并且没有隐藏,因此调用this.GetType()
和base.GetType()
的行为相同,并调用object.GetType
,返回“当前实例的确切运行时类型“正如documentation
答案 1 :(得分:2)
GetType()
始终返回当前类型,即使在base
上调用也是如此。要获得基本类型,您可以执行以下操作:
class A
{
public override int GetHashCode()
{
Console.WriteLine(this.GetType().BaseType.Name);
return 0;
}
}
BTW base.GetHashCode()
按预期工作。如果您在A
内调用它,它将执行object
实施。
答案 2 :(得分:2)
你在这里混淆了两件截然不同的事情。一个是调用什么方法实现,另一个是对象的运行时类型类型。
object.GetType()
在object
中实现,它将始终返回其调用的实例的运行时类型。
现在,当您从任何未实现Foo
的给定类调用方法Foo
,而是从基类型(您的情况)继承它时,base.Foo
或{{1基本上是相同的,因为现有的唯一Foo
是Foo
。
但是,如果该类实现了它自己的base.Foo
,那么打赌它覆盖虚拟方法或隐藏非虚方法所调用的方法将是不同的。不要被其他答案搞糊涂,说明你所看到的行为是Foo
不是虚拟的,这是不正确的。
GetType
从class A { int Foo() => 1;}
class B { }
class C { new int Foo() => 2; }
内拨打Foo
或base.Foo
是相同的,在B
内拨打电话是不是;前者将返回C
后者2
。
答案 3 :(得分:-1)
Equalsk的评论和帖子(here for brevity)是您需要知道的,但我会采取额外的步骤告诉您为什么要这样做。
鉴于class A
仅从System.Object
继承,
鉴于class B
和class C
是class A
的子类:
在B类或C类中,base.GetType().Name
将为A.您期望这是因为它是在子类中定义的,它们是从A继承的。
在A班,你仍然得到A.为什么你不想要object
?
答案很简单。假设我写了一个像这样的方法:
public static void DoStuff(A input)
{
}
我可以发送DoStuff(input)
input
为A,B或C类。这是因为他们的base
类型是A.这是可取的。我们不希望隐含地(并且容易混淆地)将A类排除在采用其衍生物的方法之外;如果我们这样做,我们希望A成为一个不可实现的接口。
将System.Object
视为祖先。如果有人问你来自哪里,你没有回应“美索不达米亚的进化”,你通常只会解决与你的存在相关的血统。 object
类本质上是原始的软泥,所以你不会引用它,除非你试图告诉它应该接受它作为参数传递的任何东西,或者不确定你将处理什么样的对象类型。
最后一个案例就是:
public void DoStuffAgain(object x)
{
Messagebox.Show(x.GetType().Name);
}
理论上,管道中的所有内容都是object
。相反,你可以传递这个你的“A”类,你想要知道“A”,因为那就是你传递它的东西。即使x的类型为object
,也是如此。
BaseType
(属性)将返回您的基础类,如其他答案中所述。但是,这不会引导您object
,除非该类没有显式继承其他内容。