[英]class casting in c#
Here is the c# code 这是C#代码
class A {
public int Foo(){ return 5;}
public virtual int Bar(){return 5;}
}
class B : A{
public new int Foo() { return 1;} //shadow
public override int Bar() {return 1;} //override
}
Output of 输出
Console.WriteLine(((A)clB).Foo()); // output 5 <<<--
Console.WriteLine(((A)clB).Bar()); // output 1
How do we get this ouput.Can anyone explain the class casting process here. 我们如何获得这个输出。任何人都可以在这里解释类转换过程。
Update: 更新:
And how does this show difference between shadowing and override 以及这如何显示阴影和替代之间的区别
I'll assume that 我假设
var clB = new B();
The difference between the Foo
and Bar
methods is that while Bar
uses inheritance and polymorphism to decide what implementation to call, the Foo
method hides it's original implementation. Foo
和Bar
方法之间的区别在于,尽管Bar
使用继承和多态性来决定要调用的实现,但是Foo
方法隐藏了其原始实现。
In, a word, A.Foo()
and B.Foo()
are completely unrelated, they just happen to have the same name. A.Foo()
, A.Foo()
和B.Foo()
完全无关,它们恰好具有相同的名称。 When the compiler sees that a variable of type A
invokes Foo
it goes in and executes A.Foo()
, since the method is not virtual, so it cannot be overriden. 当编译器看到类型A
的变量调用Foo
它将进入并执行A.Foo()
,因为该方法不是虚拟的,因此无法覆盖它。 Similarly, when it sees a variable of the type B
invoking Foo
it executes B.Foo()
, regardless of the actual type of the instance that is contained in the variable. 类似地,当看到调用Foo
B
类型的变量时,它将执行B.Foo()
,而不管该变量中包含的实例的实际类型如何。
On the other hand, the Bar
method is defined as virtual, and the inheriting classes can (and are expected to) override it's implementation. 另一方面, Bar
方法被定义为虚拟方法,并且继承的类可以(并且应该)重写其实现。 So whenever a call is made to Bar
, regardless if it is from a variable that is declared as A
or B
, the method that is actually called must be found as the "latest" implementation in the hierarchy of the calling object itself, with no impact from the type of variable that was used to refer to the object. 因此,无论何时调用Bar
,无论它来自声明为A
或B
的变量,都必须在调用对象本身的层次结构中将实际调用的方法作为“最新”实现来查找。来自用于引用对象的变量类型的影响。
In the class B
, you introduce a new
method Foo
with the same name and signature as the method already there (inherited from A
). 在类B
,您将引入一个new
方法Foo
,其名称和签名与已有方法相同(从A
继承)。 So B
has two methods with the same name. 因此, B
有两个同名方法。 That's not something you would do if you could avoid it. 如果可以避免,那不是您要做的事情。
Which of the two methods Foo
that gets called, depends on the compile-time type of the variable or expression (of type A
or B
) used. Foo
被调用的两种方法中的哪一种取决于所使用的变量或表达式(类型A
或B
)的编译时类型。
In contrast the method Bar
is virtual
. 相反,方法Bar
是virtual
。 There is only one method Bar
in B
. B
只有一种方法Bar
。 No matter what the compile-time type of the expression is, it is always the "correct" override that gets called. 无论表达式的编译时类型是什么,总是会调用“正确”的覆盖。
Writing 写作
((A)clB).Foo()
is like saying "Treat clB
as if it were an A
(if you can) and give me the result of Foo()
". 就像说“对待clB
好像它是一个A
(如果可以)并给我Foo()
的结果”一样。 Since A
has a non-virtual Foo
method, it executes A.Foo
. 由于A
具有非虚拟Foo
方法,因此它将执行A.Foo
。 Since B
's Foo
method is a " new
" method, it is not used in this instance. 由于B
的Foo
方法是“ new
”方法,因此在这种情况下不使用它。
Writing 写作
((A)clB).Bar()
is similar - "Treat clB
as if it were an A
(if you can) and give me the result of Bar()
". 相似-“将clB
当作A
对待(如果可以的话),然后给我Bar()
的结果”。 Now A
has a virtual Bar
method, meaning it can be overridden in base classes. 现在A
具有虚拟的 Bar
方法,这意味着可以在基类中覆盖它。 Since the object is really a B
, which has an override
for Foo()
, B.Foo()
is called instead. 由于该对象实际上是B
,它具有Foo()
的override
, B.Foo()
将改为调用B.Foo()
。
var clB = new B();
//Uses B's Foo method
Console.WriteLine(clB.Foo()); // output 1
//Uses A's Foo method since new was use to overload method
Console.WriteLine(((A)clB).Foo()); // output 5
//Uses B's Bar Method
Console.WriteLine(clB.Bar()); // output 1
//Uses B's Bar Method since A's Bar method was virtual
Console.WriteLine(((A)clB).Bar()); // output 1
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.