简体   繁体   中英

class casting in c#

Here is the c# code

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.

In, a word, A.Foo() and B.Foo() are completely unrelated, they just happen to have the same name. 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. 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.

On the other hand, the Bar method is defined as virtual, and the inheriting classes can (and are expected to) override it's implementation. 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.

In the class B , you introduce a new method Foo with the same name and signature as the method already there (inherited from A ). So B has two methods with the same name. 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.

In contrast the method Bar is virtual . There is only one method Bar in B . 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() ". Since A has a non-virtual Foo method, it executes A.Foo . Since B 's Foo method is a " new " method, it is not used in this instance.

Writing

((A)clB).Bar()

is similar - "Treat clB as if it were an A (if you can) and give me the result of Bar() ". Now A has a virtual Bar method, meaning it can be overridden in base classes. Since the object is really a B , which has an override for Foo() , B.Foo() is called instead.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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