agasthyan
agasthyan

Reputation: 725

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

Upvotes: 2

Views: 155

Answers (4)

SWeko
SWeko

Reputation: 30882

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.

Upvotes: 6

Dustin Kingen
Dustin Kingen

Reputation: 21245

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

Upvotes: 0

D Stanley
D Stanley

Reputation: 152521

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.

Upvotes: 0

Jeppe Stig Nielsen
Jeppe Stig Nielsen

Reputation: 61952

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.

Upvotes: 0

Related Questions