How Dynamic Binding (with hiding) works? - c#

I have been practicing Dynamic Binding (with hiding) and i came across a code block like below.
The output of the program is:
"I am a B"
And I just couldn't understand it.
Can anyone can explain it to me? Thanks in advance.
class A
{
public virtual void WhoAreYou() { Console.WriteLine("I am an A"); }
}
class B : A
{
public override void WhoAreYou() { Console.WriteLine("I am a B"); }
}
class C : B
{
public new virtual void WhoAreYou() { Console.WriteLine("I am a C"); }
}
class D : C
{
public override void WhoAreYou() { Console.WriteLine("I am a D"); }
}
A a = new D();
a.WhoAreYou(); // "I am a B" !!

The "trick" here is in this line: public **new** virtual void WhoAreYou(). This creates a new virtual member in class C, instead of overriding the base implementation. Therefore, the virtual call a.WhoAreYou() with the static type of A resolves to B because public override void WhoAreYou() in B overrides the implementation of A, but does not get overriden further.
If you where to do
C c = new D();
c.WhoAreYou(); // "I am a D" !!
this would resolve to D. In this case, the methods WhoAreYou of C/D and of A/B are completely distinct and the effect would be the same if they had entirely different names.
This is a very rare scenario, I have actually not seen any commonly used APIs that use the concept to declare a method new virtual, because it's confusing.

Related

C# polymorphism - upcasting

I would like to ask you for an explanation of this example:
public class A : B
{
public override void Method()
{
Console.WriteLine("A");
}
}
public class B
{
public virtual void Method()
{
Console.WriteLine("B");
}
}
Equation:
void Main()
{
B b = (B)new A();
b.Method(); // result A
}
Why upcasting did not work in this case?
How microsoft docs say:
If you want your derived class to have a member with the same name as a member in a base class, you can use the new keyword to hide the base class member. The new keyword is put before the return type of a class member that is being replaced. The following code provides an example:

Build dynamic type to simulate python multi-inheritance

I want to build a dynamic type at run-time to compose multiple existing types in one dynamic type to simulate the following python scenario:
class A(object):
def Confirm(self):
print("A")
class B(A):
def Confirm(self):
super().Confirm()
print("B")
class C(A):
def Confirm(self):
print("C")
super().Confirm()
class D(A):
def Confirm(self):
print("D")
super().Confirm()
print("DD")
class E(B,C,D):
pass
I got the below outputs:
C
D
A
DD
B
so the call stack respects code order before and after super() call, executing all codes before super() call then super call itself finally the last part of code that comes after super() call.
I want to simulate that behavior in c#.
public class A
{
public virtual void Confirm()
{
Console.Writeline("A");
}
}
public class B : A
{
public virtual void Confirm()
{
base.Confirm();
Console.Writeline("B");
}
}
public class C : A
{
public virtual void Confirm()
{
Console.Writeline("C");
base.Confirm();
}
}
public class D : A
{
public virtual void Confirm()
{
Console.Writeline("D");
base.Confirm();
Console.Writeline("DD");
}
}
public class E : A
{
public virtual void Confirm()
{
// BEFORE base
Console.Writeline("C"); // C.Confirm() without base, only code before base.Confirm()
Console.Writeline("D"); // D.Confirm() without base only code before base.Confirm()
// BASE
base.Confirm(); // base itself (A)
// AFTER base
Console.Writeline("DD"); // return to D.Confirm() only the code after base.Confirm()
Console.Writeline("B"); // B.Confirm() have only a code after base.Confirm() call
}
}
i think i can solve the problem with using of the System.Reflection.Emit but i don't know if that possible.
Your question could be rephrased as "How do I build a compiler that supports multiple inheritance and runs on the CLR". If that's really the path you want to go down through, I'd start here and try to read up on the VTable stuff Brumme mentions.
There is also this SO question which shows how, more or less, MC++ emulates multiple inheritance by simply holding base class instances as instance members of the derived type. Note, however, that in your case you would have to solve the diamond problem (inheriting from two or more base classes that have a common base class) differently, applying that solution blindly will cause A.Confirm() to be called thrice. To change that, your compiler would have to first flatten the inheritance hierarchy and then split all methods containing calls to base into multiple methods. So something like this:
public class A
{
public virtual void Confirm()
{
Console.Writeline("A");
}
}
public class B : A
{
public virtual void Confirm()
{
base.Confirm();
Console.Writeline("B");
}
protected void Confirm_Before1()
{
}
protected void Confirm_After1()
{
Console.WriteLine("B");
}
}
public class C : A
{
public virtual void Confirm()
{
Console.Writeline("C");
base.Confirm();
}
protected void Confirm_Before1()
{
Console.Writeline("C");
}
protected void Confirm_After1()
{
}
}
public class D : A
{
public virtual void Confirm()
{
Console.Writeline("D");
base.Confirm();
Console.Writeline("DD");
}
protected void Confirm_Before1()
{
Console.Writeline("D");
}
protected void Confirm_After1()
{
Console.WriteLine("DD");
}
}
public class E : A
{
private readonly B _baseB = new B();
private readonly C _baseC = new C();
private readonly D _baseD = new D();
public virtual void Confirm()
{
_baseB.Confirm_Before1();
_baseC.Confirm_Before1();
_baseD.Confirm_Before1();
base.Confirm();
_baseB.Confirm_After1();
_baseC.Confirm_After1();
_baseD.Confirm_After1();
}
}
Your hypothetical compiler would have to parse the inheritance hierarchy, find all methods accessible from your multiply-inheriting type, split them into N+1 methods, where N is the number of base calls within them and call them all in order in your overloaded method.
Things get infintely more complicated if you change your example, however. What if A had an additional method Foo, B.Confirm() was:
public virtual void Confirm()
{
base.Foo();
Confirm.WriteLine("B");
}
and C.Confirm() was
public virtual void Confirm()
{
Confirm.WriteLine("C");
base.Foo();
}
What do you expect of E.Confirm()? Will it call Foo once or twice? And what if there were multiple calls to Foo in B.Confirm() but not in C.Confirm()? I have little idea on how Python handles this, it's enough to say that simply changing the B class to
class B(A):
def Confirm(self):
super().Confirm()
print("B")
super().Confirm()
and calling E.Confirm results in
C
D
A
DD
B
C
D
A
DD
That looks just baffling to me, which is a part of why MI is so hard.
Either way, the final answer is that if you want Python-esque behaviour, you'd have to implement a compiler that looks for multiple inheritance one way or another (most likely using an attribute) and transforms the code to do exactly what Python does. A concrete solution is way beyond an answer to an SO question, but if you run into any specific trouble implementing this crazy idea then feel free to ask another one.
EDIT:
As a PSA, I think that I should mention: if this is not just a fun exercise/thought experiment that you're doing, but rather you're trying to solve a real problem - this is not the way. Redesign your system to not rely on MI, or, if you're fond of the Python MI, don't use C#.
I rewrote the python a little bit
class A(object):
def Confirm(self):
print("A")
class B(A):
def Confirm(self):
print("B.Confirm ENTER")
super().Confirm() # E forces that it will call C.Confirm()
print("B.Confirm EXIT")
class C(A):
def Confirm(self):
print("C.Confirm ENTER")
super().Confirm() # E forces that it will call D.Confirm()
print("C.Confirm EXIT")
class D(A):
def Confirm(self):
print("D.Confirm ENTER")
super().Confirm()
print("D.Confirm EXIT")
class E(B,C,D):
pass
e = E()
e.Confirm()
and here a C# code with the same output
using System;
public class Program
{
public static void Main()
{
var e = new E();
e.Confirm();
}
}
class A
{
public virtual void Confirm()
{
Console.WriteLine("A");
}
}
class B : C
{
public override void Confirm()
{
Console.WriteLine("B.Confirm ENTER");
base.Confirm();
Console.WriteLine("B.Confirm EXIT");
}
}
class C : D
{
public override void Confirm()
{
Console.WriteLine("C.Confirm ENTER");
base.Confirm();
Console.WriteLine("C.Confirm EXIT");
}
}
class D : A
{
public override void Confirm()
{
Console.WriteLine("D.Confirm ENTER");
base.Confirm();
Console.WriteLine("D.Confirm EXIT");
}
}
class E : B
{
}
live view at .net fiddle
output of both codes
B.Confirm ENTER
C.Confirm ENTER
D.Confirm ENTER
A
D.Confirm EXIT
C.Confirm EXIT
B.Confirm EXIT

override ToString() with override and new keyword

I am new in c#.confuse with this question.
I Have override ToString() with override and new keyword.both are give me same output.then what is the difference between both.
here is my Example
class A
{
public new string ToString()
{
return "With New Keyword";
}
}
class B
{
public override string ToString()
{
return "With Override Keyword";
}
}
class Program
{
static void Main(string[] args)
{
A a = new A();
B b = new B();
Console.WriteLine(a.ToString());
Console.WriteLine(b.ToString());
Console.Read();
}
}
Output
With New Keyword
With Override Keyword
I know its a silly question.
please anyone help me to give me difference between both methods.
I am not asking about difference between new and override key word.I want to know that difference between both method.In concept of Override Object methods.
It makes a difference when you do this:
object a = new A(); // notice the type of the variable here!
object b = new B();
Console.WriteLine(a.ToString());
Console.WriteLine(b.ToString());
a.ToString() will not call your implementation of ToString and will instead call object.ToString, which returns the fully qualified type name of the object. b.ToString() will call your implementation.
What you did in B is called overriding. What you did in A is called hiding. Hiding loses its effect when the compile time type of a variable is not that type anymore. Your implementation of ToString will only be called when the compile time type is A.
Learn more here.
You can easily google this.
From MSDN
In C#, a method in a derived class can have the same name as a method
in the base class. You can specify how the methods interact by using
the new and override keywords. The override modifier extends the base
class method, and the new modifier hides it. The difference is
illustrated in the examples in this topic.
In a console application, declare the following two classes, BaseClass
and DerivedClass. DerivedClass inherits from BaseClass.
In class B you are overriding ToString() method that is Object.ToString() because you have not inherited A. Now consider below example,
class A
{
public string ReturnString()
{
return "ClassA::Method";
}
}
class B : A
{
public newstring ReturnString()
{
return "ClassB::Method";
}
}
class Program
{
static void Main(string[] args)
{
A a = new A();
B b = new B();
Console.WriteLine(a.ToString());
Console.WriteLine(b.ToString());
Console.Read();
}
}
Here you are hiding the method in class B as you have inherited Class A. So you will get the output as ClassA::Method for both method calls.
Now consider below example
class A
{
public virtual string ReturnString()
{
return "ClassA::Method";
}
}
class B : A
{
public override string ReturnString()
{
return "ClassB::Method";
}
}
class Program
{
static void Main(string[] args)
{
A a = new A();
B b = new B();
Console.WriteLine(a.ToString());
Console.WriteLine(b.ToString());
Console.Read();
}
}
Here we have overridden the Class A's method in Class B. This means ClassB method is like extension or you can say it has different meaning than ClassA. You will get output like below
ClassA::Method
ClassB::Method

Is using reflection to find type of abstract property a code smell?

So say I have three classes: A, B, and C. A is abstract, B and C inherit from A.
I have created a list of A classes. In a function, I need to know the type of the class I have: A, B, or C. Do I use reflection to get the name? Assign it a type variable and check that? Or am I using abstraction fundamentally wrong?
public abstract class A
{
public string Type
{
get;
set;
}
}
public class B : A
{
public B()
{
this.Type = "B";
Console.WriteLine("I am of type B!");
}
}
public class C : A
{
public C()
{
this.Type = "C";
Console.WriteLine("I am of type C!");
}
}
List<A> listOfStuff = new List<A>();
void doSomething()
{
listOfStuff.Add(new A());
listOfStuff.Add(new B());
listOfStuff.Add(new C());
foreach (A item in listOfStuff)
{
doOperation(item);
}
}
void doOperation(A thing1)
{
//Is this bad practice?
if (thing1.GetType().Name == "B")
{
//Do code
}
//Or what about this?
if (thing1.Type == "B")
{
//Do code
}
}
This is perhaps a violation of the Liskov substitution principle, the L in SOLID. If a bunch of "A"s are in a list, it should be possible to operate on them without "knowing" their subtype. If they're all going to be cast as A but then you have to reinspect them to determine their actual type and handle them differently then it defeats the purpose of being able to refer to them by their base type.
If the different types can all expose the same properties (describing area, dimensions, etc.) then an interface might be better than an abstract class.
No need to work that hard. Just use is
public abstract class A
{
}
public class B : A
{
public B()
{
Console.WriteLine("I am of type B!");
}
}
public class C : A
{
public C()
{
Console.WriteLine("I am of type C!");
}
}
static List<A> listOfStuff = new List<A>();
public static void doSomething()
{
listOfStuff.Add(new B());
listOfStuff.Add(new C());
foreach (A item in listOfStuff)
{
doOperation(item);
}
}
static void doOperation(A thing1)
{
if (thing1 is B)
{
//Do code for B
}
if (thing1 is C)
{
//Do code for C
}
}
Rob Deary has already shown you how to avoid doing it but he didn't specifically answer your question.
I would say that "code smell" is far too mild a term for what you wrote in your OP. The only good case I can see for using reflection to find an object's type is some sort of logging or reporting function. (Something that's going to print "I got a B".) It would be possibly tolerable if it was needed to work around a bug in code you couldn't fix. Beyond that don't do it.

How to call base.base.method()?

// Cannot change source code
class Base
{
public virtual void Say()
{
Console.WriteLine("Called from Base.");
}
}
// Cannot change source code
class Derived : Base
{
public override void Say()
{
Console.WriteLine("Called from Derived.");
base.Say();
}
}
class SpecialDerived : Derived
{
public override void Say()
{
Console.WriteLine("Called from Special Derived.");
base.Say();
}
}
class Program
{
static void Main(string[] args)
{
SpecialDerived sd = new SpecialDerived();
sd.Say();
}
}
The result is:
Called from Special Derived.
Called from Derived. /* this is not expected */
Called from Base.
How can I rewrite SpecialDerived class so that middle class "Derived"'s method is not called?
UPDATE:
The reason why I want to inherit from Derived instead of Base is Derived class contains a lot of other implementations. Since I can't do base.base.method() here, I guess the best way is to do the following?
// Cannot change source code
class Derived : Base
{
public override void Say()
{
CustomSay();
base.Say();
}
protected virtual void CustomSay()
{
Console.WriteLine("Called from Derived.");
}
}
class SpecialDerived : Derived
{
/*
public override void Say()
{
Console.WriteLine("Called from Special Derived.");
base.Say();
}
*/
protected override void CustomSay()
{
Console.WriteLine("Called from Special Derived.");
}
}
Just want to add this here, since people still return to this question even after many time. Of course it's bad practice, but it's still possible (in principle) to do what author wants with:
class SpecialDerived : Derived
{
public override void Say()
{
Console.WriteLine("Called from Special Derived.");
var ptr = typeof(Base).GetMethod("Say").MethodHandle.GetFunctionPointer();
var baseSay = (Action)Activator.CreateInstance(typeof(Action), this, ptr);
baseSay();
}
}
This is a bad programming practice, and not allowed in C#. It's a bad programming practice because
The details of the grandbase are implementation details of the base; you shouldn't be relying on them. The base class is providing an abstraction overtop of the grandbase; you should be using that abstraction, not building a bypass to avoid it.
To illustrate a specific example of the previous point: if allowed, this pattern would be yet another way of making code susceptible to brittle-base-class failures. Suppose C derives from B which derives from A. Code in C uses base.base to call a method of A. Then the author of B realizes that they have put too much gear in class B, and a better approach is to make intermediate class B2 that derives from A, and B derives from B2. After that change, code in C is calling a method in B2, not in A, because C's author made an assumption that the implementation details of B, namely, that its direct base class is A, would never change. Many design decisions in C# are to mitigate the likelihood of various kinds of brittle base failures; the decision to make base.base illegal entirely prevents this particular flavour of that failure pattern.
You derived from your base because you like what it does and want to reuse and extend it. If you don't like what it does and want to work around it rather than work with it, then why did you derive from it in the first place? Derive from the grandbase yourself if that's the functionality you want to use and extend.
The base might require certain invariants for security or semantic consistency purposes that are maintained by the details of how the base uses the methods of the grandbase. Allowing a derived class of the base to skip the code that maintains those invariants could put the base into an inconsistent, corrupted state.
You can't from C#. From IL, this is actually supported. You can do a non-virt call to any of your parent classes... but please don't. :)
The answer (which I know is not what you're looking for) is:
class SpecialDerived : Base
{
public override void Say()
{
Console.WriteLine("Called from Special Derived.");
base.Say();
}
}
The truth is, you only have direct interaction with the class you inherit from. Think of that class as a layer - providing as much or as little of it or its parent's functionality as it desires to its derived classes.
EDIT:
Your edit works, but I think I would use something like this:
class Derived : Base
{
protected bool _useBaseSay = false;
public override void Say()
{
if(this._useBaseSay)
base.Say();
else
Console.WriteLine("Called from Derived");
}
}
Of course, in a real implementation, you might do something more like this for extensibility and maintainability:
class Derived : Base
{
protected enum Mode
{
Standard,
BaseFunctionality,
Verbose
//etc
}
protected Mode Mode
{
get; set;
}
public override void Say()
{
if(this.Mode == Mode.BaseFunctionality)
base.Say();
else
Console.WriteLine("Called from Derived");
}
}
Then, derived classes can control their parents' state appropriately.
Why not simply cast the child class to a specific parent class and invoke the specific implementation then? This is a special case situation and a special case solution should be used. You will have to use the new keyword in the children methods though.
public class SuperBase
{
public string Speak() { return "Blah in SuperBase"; }
}
public class Base : SuperBase
{
public new string Speak() { return "Blah in Base"; }
}
public class Child : Base
{
public new string Speak() { return "Blah in Child"; }
}
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Child childObj = new Child();
Console.WriteLine(childObj.Speak());
// casting the child to parent first and then calling Speak()
Console.WriteLine((childObj as Base).Speak());
Console.WriteLine((childObj as SuperBase).Speak());
}
}
public class A
{
public int i = 0;
internal virtual void test()
{
Console.WriteLine("A test");
}
}
public class B : A
{
public new int i = 1;
public new void test()
{
Console.WriteLine("B test");
}
}
public class C : B
{
public new int i = 2;
public new void test()
{
Console.WriteLine("C test - ");
(this as A).test();
}
}
You can also make a simple function in first level derived class, to call grand base function
My 2c for this is to implement the functionality you require to be called in a toolkit class and call that from wherever you need:
// Util.cs
static class Util
{
static void DoSomething( FooBase foo ) {}
}
// FooBase.cs
class FooBase
{
virtual void Do() { Util.DoSomething( this ); }
}
// FooDerived.cs
class FooDerived : FooBase
{
override void Do() { ... }
}
// FooDerived2.cs
class FooDerived2 : FooDerived
{
override void Do() { Util.DoSomething( this ); }
}
This does require some thought as to access privilege, you may need to add some internal accessor methods to facilitate the functionality.
In cases where you do not have access to the derived class source, but need all the source of the derived class besides the current method, then I would recommended you should also do a derived class and call the implementation of the derived class.
Here is an example:
//No access to the source of the following classes
public class Base
{
public virtual void method1(){ Console.WriteLine("In Base");}
}
public class Derived : Base
{
public override void method1(){ Console.WriteLine("In Derived");}
public void method2(){ Console.WriteLine("Some important method in Derived");}
}
//Here should go your classes
//First do your own derived class
public class MyDerived : Base
{
}
//Then derive from the derived class
//and call the bass class implementation via your derived class
public class specialDerived : Derived
{
public override void method1()
{
MyDerived md = new MyDerived();
//This is actually the base.base class implementation
MyDerived.method1();
}
}
As can be seen from previous posts, one can argue that if class functionality needs to be circumvented then something is wrong in the class architecture. That might be true, but one cannot always restructure or refactor the class structure on a large mature project. The various levels of change management might be one problem, but to keep existing functionality operating the same after refactoring is not always a trivial task, especially if time constraints apply. On a mature project it can be quite an undertaking to keep various regression tests from passing after a code restructure; there are often obscure "oddities" that show up.
We had a similar problem in some cases inherited functionality should not execute (or should perform something else). The approach we followed below, was to put the base code that need to be excluded in a separate virtual function. This function can then be overridden in the derived class and the functionality excluded or altered. In this example "Text 2" can be prevented from output in the derived class.
public class Base
{
public virtual void Foo()
{
Console.WriteLine("Hello from Base");
}
}
public class Derived : Base
{
public override void Foo()
{
base.Foo();
Console.WriteLine("Text 1");
WriteText2Func();
Console.WriteLine("Text 3");
}
protected virtual void WriteText2Func()
{
Console.WriteLine("Text 2");
}
}
public class Special : Derived
{
public override void WriteText2Func()
{
//WriteText2Func will write nothing when
//method Foo is called from class Special.
//Also it can be modified to do something else.
}
}
There seems to be a lot of these questions surrounding inheriting a member method from a Grandparent Class, overriding it in a second Class, then calling its method again from a Grandchild Class. Why not just inherit the grandparent's members down to the grandchildren?
class A
{
private string mystring = "A";
public string Method1()
{
return mystring;
}
}
class B : A
{
// this inherits Method1() naturally
}
class C : B
{
// this inherits Method1() naturally
}
string newstring = "";
A a = new A();
B b = new B();
C c = new C();
newstring = a.Method1();// returns "A"
newstring = b.Method1();// returns "A"
newstring = c.Method1();// returns "A"
Seems simple....the grandchild inherits the grandparents method here. Think about it.....that's how "Object" and its members like ToString() are inherited down to all classes in C#. I'm thinking Microsoft has not done a good job of explaining basic inheritance. There is too much focus on polymorphism and implementation. When I dig through their documentation there are no examples of this very basic idea. :(
I had the same problem as the OP, where I only wanted to override a single method in the middle Class, leaving all other methods alone. My scenario was:
Class A - base class, DB access, uneditable.
Class B : A - "record type" specific functionality (editable, but only if backward compatible).
Class C : B - one particular field for one particular client.
I did very similar to the second part of the OP posting, except I put the base call into it's own method, which I called from from Say() method.
class Derived : Base
{
public override void Say()
{
Console.WriteLine("Called from Derived.");
BaseSay();
}
protected virtual void BaseSay()
{
base.Say();
}
}
class SpecialDerived : Derived
{
public override void Say()
{
Console.WriteLine("Called from Special Derived.");
base.BaseSay();
}
}
You could repeat this ad infinitum, giving, for example SpecialDerived a BaseBaseSay() method if you needed an ExtraSpecialDerived override to the SpecialDerived.
The best part of this is that if the Derived changes its inheritance from Base to Base2, all other overrides follow suit without needing changes.
If you want to access to base class data you must use "this" keyword or you use this keyword as reference for class.
namespace thiskeyword
{
class Program
{
static void Main(string[] args)
{
I i = new I();
int res = i.m1();
Console.WriteLine(res);
Console.ReadLine();
}
}
public class E
{
new public int x = 3;
}
public class F:E
{
new public int x = 5;
}
public class G:F
{
new public int x = 50;
}
public class H:G
{
new public int x = 20;
}
public class I:H
{
new public int x = 30;
public int m1()
{
// (this as <classname >) will use for accessing data to base class
int z = (this as I).x + base.x + (this as G).x + (this as F).x + (this as E).x; // base.x refer to H
return z;
}
}
}

Categories