class casting in c# - 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

Related

C# new in object declaration when inherit and override

For example,
public class Foo
{
public virtual bool DoSomething() { return false; }
}
public class Bar : Foo
{
public override bool DoSomething() { return true; }
}
public class Test
{
public static void Main()
{
Foo test = new Bar();
Console.WriteLine(test.DoSomething());
}
}
Why is the answer True? What does "new Bar()" mean? Doesn't "new Bar()" just mean allocate the memory?
new Bar() actually makes a new object of type Bar.
The difference between virtual/override and new (in the context of a method override) is whether you want the compiler to consider the type of the reference or the type of the object in determining which method to execute.
In this case, you have a reference of type "reference to Foo" named test, and this variable references an object of type Bar. Because DoSomething() is virtual and overridden, this means it will call Bar's implementation and not Foo's.
Unless you use virtual/override, C# only considers the type of the reference. That is, any variable of type "reference to Foo" would call Foo.DoSomething() and any "reference to Bar" would call Bar.DoSomething() no matter what type the objects being referenced actually were.
new Bar() means create a new Bar object and call the default constructor (which does nothing in this case).
It returns true because test.DoSomething() returns true, as it has an override for Foo implementation (so the Foo implementation will not be called).
Foo test = new Bar();
test is referring to a new object of Bar, hence the call test.DoSomething() calls the DoSomething() of the object Bar. This returns true.

Why is method overloading not working in this C# program?

namespace test
{
class Program
{
static void Main(string[] args)
{
Derived obj = new Derived();
int i = 10;
obj.Foo(i);
Console.ReadLine();
}
}
class Base
{
public virtual void Foo(int i)
{
Console.WriteLine("Base:Foo()");
}
}
class Derived:Base
{
public override void Foo(int i)
{
Console.WriteLine("Foo(int)");
}
public void Foo(object i)
{
Console.WriteLine("Foo(object)");
}
}
}
output of the program according to me should be Foo(int) but output is coming as Foo(object) please help me in understanding the diffrence in output
Good question, I can reproduce your results. If one takes a look at the C# specifications one will find the following snippets:
7.5.3 Overload resolution
For example, the set of candidates for a method invocation does not
include methods marked override (§7.4), and methods in a base class
are not candidates if any method in a derived class is applicable
(§7.6.5.1).
7.4 Member Lookup
Otherwise, the set consists of all accessible (§3.5) members named N
in T, including inherited members and the accessible members named N
in object. If T is a constructed type, the set of members is obtained
by substituting type arguments as described in §10.3.2. Members that
include an override modifier are excluded from the set.
7.6.5.1 Method invocations
The set of candidate methods is reduced to contain only methods from
the most derived types: For each method C.F in the set, where C is the
type in which the method F is declared, all methods declared in a base
type of C are removed from the set. Furthermore, if C is a class type
other than object, all methods declared in an interface type are
removed from the set.
Sounds a bit complicated? Even the C# designers seem to think so and put in the 'helpful' note:
7.6.5.1 Method invocations
The intuitive effect of the resolution rules described above is as
follows: To locate the particular method invoked by a method
invocation, start with the type indicated by the method invocation and
proceed up the inheritance chain until at least one applicable,
accessible, non-override method declaration is found. Then perform
type inference and overload resolution on the set of applicable,
accessible, non-override methods declared in that type and invoke the
method thus selected. If no method was found, try instead to process
the invocation as an extension method invocation.
If we take a look at your derived class, we see two possible methods for C# to use:
A) public override void Foo(int i)
B) public void Foo(object i)
Let's use that last checklist!
Applicability - Both A and B are applicable -(both are void, both are named 'Foo' and both can accept an integer value).
Accessibility - Both A and B are accessible (public)
Not Overridden - Only B is not overridden.
But wait you might say! A is more specific than B!
Correct, but that consideration is only made after we've disregarded option A. As Eric Lippert (one of the designers) puts it Closer is always better than farther away. (Thanks Anthony Pegram)
Addendum
There is always the 'new' keyword:
class Derived : Base
{
public new void Foo(int i)
{
Console.WriteLine("Foo(int)");
}
public void Foo(object i)
{
Console.WriteLine("Foo(object)");
}
}
Though the specifics of that best left for another question!
The simple datatype int descends from object. You are overriding the function and also overloading the parameter list. Since the function name is the same with a different signature the compiler allows this. For simple objects, I image one copy of the parameter signature in the most basic form is stored in the method table.

How to call overridden method which have overloads?

I have the following simple code
abstract class A
{
public abstract void Test(Int32 value);
}
class B : A
{
public override void Test(Int32 value)
{
Console.WriteLine("Int32");
}
public void Test(Double value)
{
Test((Int32)1);
}
}
When I ran this code the line Test((Int32)1) causes stack overflow due to infinite recursion. The only possible way to correctly call proper method (with integer parameter) I found is
(this as A).Test(1);
But this is not appropriate for me, because both methods Test are public and I am willing the users to be able to call both method?
Method overload resolution in C# does not always behave as you might expect, but your code is behaving according to the specification (I wrote a blog post about this a while ago).
In short, the compiler start off by finding methods that
Has the same name (in your case Test)
are declared in the type (in your case B) or one of its base types
are not declared with the override modifier
Note that last point. This is actually logical, since virtual methods are resolved in run-time, not compile time.
Finally, if the type (in this case B) has a method that is a candidate (which means that the parameters in your call can be implicitly converted to the parameter type of the candidate method), that method will be used. Your overridden method is not even part of the decision process.
If you want to call your overridden method, you will need to cast the object to its base type first.
Unfortunately in order to call the A::Test(int) through a B reference some sort of cast is needed. So long as the C# compiler sees the reference through B it will pick the B::Test(double) version.
A slightly less ugly version is the following
((A)this).Test(1);
Another thought though is have a private method with a different name that both feed into.
class B : A {
public override void Test(int i) {
TestCore(i);
}
public void Test(double d) {
TestCore(1);
}
private void TestCore(int i) {
// Combined logic here
}
}

Can I use some other class's function as a delegate?

Say I have 2 classes, class A and class B. Class A creates an instance of Class B. Class A has a function that I would like to pass into a method from Class B.
class A {
void Main(string[] args) {
B classB=new B();
DelegateCaller(new delFunction(classB.TheFunction()); // <-- Won't compile (method name expected)
DelegateCaller(new delFunction(B.TheFunction()); // <-- Won't compile (object reference is req'd)
}
public delegate string delFunction();
public DelegateCaller(delFunction func) {
System.Console.WriteLine(func());
}
}
class B {
public string TheFunction() {
return "I'm Printing!!!";
}
}
I'm not sure if it a syntax issue or it's just something I can't do. Maybe I need to define the delegate in B, but reference it in A? What about B's this pointer?
It's just a syntax issue; get rid of the parentheses after classB.TheFunction - they indicate that you wish to invoke the method.
DelegateCaller(new delFunction(classB.TheFunction));
Do note that there is an implicit conversion available from a method-group, so you can just do:
DelegateCaller(classB.TheFunction);
Also note that creating your own delegate-type in this case is unnecessary; you could just use the in-built Func<string> type.
EDIT: As Darin Dimitrov points out, there is also the unrelated issue of calling an instance method as though it were a static method.
Try like this:
class A
{
static void Main()
{
B classB = new B();
DelegateCaller(classB.TheFunction);
}
public delegate string delFunction();
public static void DelegateCaller(delFunction func)
{
Console.WriteLine(func());
}
}
class B
{
public string TheFunction()
{
return "I'm Printing!!!";
}
}
Let me elaborate about the different changes I've made to your initial code:
TheFunction in class B needs to be public so that you can access it from class A
The DelegateCaller method in class A should be static and not necessarily return a value (declare it as void) if you want to call it from the static Main method.
The definition of the delFunction delegate should return a string.
Take the parenthesis off the end of TheFunction. You want the method, not the result of a call to the method.
If you want to capture an instance method for usage in a general purpose fashion you should use Delegate.CreateDelegate(Type,MethodInfo). This is nice as it allows you to create an "open delegate" meaning it isn't bound to an instance and can take any instance that is a ClassB. It makes reflection quite fast if you know the type information, as this method will perform much faster than the equivalent statement using MethodInfo.Invoke.
DelegateCaller(new delFunction(B.TheFunction());
Should be
DelegateCaller(new delFunction(B.TheFunction);
To use classB.TheFunction you would need to make TheFunction static. You pass in the function with no parens.

Why does this polymorphic C# code print what it does?

I was recently given the following piece of code as a sort-of puzzle to help understand Polymorphism and Inheritance in OOP - C#.
// No compiling!
public class A
{
public virtual string GetName()
{
return "A";
}
}
public class B:A
{
public override string GetName()
{
return "B";
}
}
public class C:B
{
public new string GetName()
{
return "C";
}
}
void Main()
{
A instance = new C();
Console.WriteLine(instance.GetName());
}
// No compiling!
Now, after a long, long chat with the other developer who presented the puzzle, I know what the output is, but I won't spoil it for you. The only issue I'm really having is how we get to that output, how the code steps through, what's inheriting what, etc.
I thought C would be returned as that seems to be the class that is defined. Then I went through my head as to whether B would be returned because C inherits B - but B also inherits A (which is where I got confused!).
Question:
Could anyone explain how polymorphism and inheritance play their part in retrieving the output, eventually displayed on screen?
The correct way to think about this is to imagine that every class requires its objects to have a certain number of "slots"; those slots are filled with methods. The question "what method actually gets called?" requires you to figure out two things:
What are the contents of each slot?
Which slot is called?
Let's start by considering the slots. There are two slots. All instances of A are required to have a slot we'll call GetNameSlotA. All instances of C are required to have a slot we'll call GetNameSlotC. That's what the "new" means on the declaration in C -- it means "I want a new slot". Compared to the "override" on the declaration in B, which means "I do not want a new slot, I want to re-use GetNameSlotA".
Of course, C inherits from A, so C must also have a slot GetNameSlotA. Therefore, instances of C have two slots -- GetNameSlotA, and GetNameSlotC. Instances of A or B which are not C have one slot, GetNameSlotA.
Now, what goes into those two slots when you create a new C? There are three methods, which we'll call GetNameA, GetNameB, and GetNameC.
The declaration of A says "put GetNameA in GetNameSlotA". A is a superclass of C, so A's rule applies to C.
The declaration of B says "put GetNameB in GetNameSlotA". B is a superclass of C, so B's rule applies to instances of C. Now we have a conflict between A and B. B is the more derived type, so it wins -- B's rule overrides A's rule. Hence the word "override" in the declaration.
The declaration of C says "put GetNameC in GetNameSlotC".
Therefore, your new C will have two slots. GetNameSlotA will contain GetNameB and GetNameSlotC will contain GetNameC.
We've now determined what methods are in what slots, so we've answered our first question.
Now we have to answer the second question. What slot is called?
Think about it like you're the compiler. You have a variable. All you know about it is that it is of type A. You're asked to resolve a method call on that variable. You look at the slots available on an A, and the only slot you can find that matches is GetNameSlotA. You don't know about GetNameSlotC, because you only have a variable of type A; why would you look for slots that only apply to C?
Therefore this is a call to whatever is in GetNameSlotA. We've already determined that at runtime, GetNameB will be in that slot. Therefore, this is a call to GetNameB.
The key takeaway here is that in C# overload resolution chooses a slot and generates a call to whatever happens to be in that slot.
It should return "B" because B.GetName() is held in the little virtual table box for the A.GetName() function. C.GetName() is a compile time "override", it doesn't override the virtual table so you can't retrieve it through a pointer to A.
Easy, you only have to keep the inheritance tree in mind.
In your code, you hold a reference to a class of type 'A', which is instantiated by an instance of type 'C'. Now, to resolve the exact method address for the virtual 'GetName()' method, the compiler goes up the inheritance hierarchy and looks for the most recent override (note that only 'virtual' is an override, 'new' is something completely different...).
That's in short what happens. The new keyword from type 'C' would only play a role if you would call it on an instance of type 'C' and the compiler then would negate all possible inheritance relations altogether. Strictly spoken, this has nothing to do at all with polymorphism - you can see that from the fact that whether you mask a virtual or non-virtual method with the 'new' keyword doesn't make any difference...
'New' in class 'C' means exactly that: If you call 'GetName()' on an instance of this (exact) type, then forget everything and use THIS method. 'Virtual' in contrary means: Go up the inheritance tree until you find a method with this name, no matter what the exact type of the calling instance is.
OK, the post is a bit old, but it's an excellent question and an excellent answer, so I just wanted to add my thoughts.
Consider the following example, which is the same as before, except for the main function:
// No compiling!
public class A
{
public virtual string GetName()
{
return "A";
}
}
public class B:A
{
public override string GetName()
{
return "B";
}
}
public class C:B
{
public new string GetName()
{
return "C";
}
}
void Main()
{
Console.Write ( "Type a or c: " );
string input = Console.ReadLine();
A instance = null;
if ( input == "a" ) instance = new A();
else if ( input == "c" ) instance = new C();
Console.WriteLine( instance.GetName() );
}
// No compiling!
Now it's really obvious that the function call cannot be bound to a specific function at compile time. Something must be compiled however, and that information can only depend on the type of the reference. So, it would be impossible to execute the GetName function of class C with any reference other than one of type C.
P.S. Maybe I should've used the term method in stead of function, but as Shakespeare said: A function by any other name is still a function :)
Actually, I think it should display C, because new operator just hides all ancestor methods with the same name. So, with methods of A and B hidden, only C remains visible.
http://msdn.microsoft.com/en-us/library/51y09td4%28VS.71%29.aspx#vclrfnew_newmodifier

Categories

Resources