简体   繁体   English

C#中的类转换

[英]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. FooBar方法之间的区别在于,尽管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 ,无论它来自声明为AB的变量,都必须在调用对象本身的层次结构中将实际调用的方法作为“最新”实现来查找。来自用于引用对象的变量类型的影响。

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被调用的两种方法中的哪一种取决于所使用的变量或表达式(类型AB )的编译时类型。

In contrast the method Bar is virtual . 相反,方法Barvirtual 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. 由于BFoo方法是“ 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()overrideB.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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM