Could someone please explain what the difference is between these two examples?
Class A
protected virtual string GetData()
Class B
private override string GetData()
And the following:
Class A
protected string GetData()
Class B
private string GetData()
Assuming that 'Class B' inherits from 'Class A'.
I always assumed that you need to use virtual in the superclass and override in the subclass if you want overriding of a method, however I tried removing the keywords and the program compiled fine. What exactly is the difference, if any?
The second example that you showed hides the GetData of the parent, it doesn't override it.
Example:
private class Base
{
public virtual void Test()
{
Console.WriteLine("Base");
}
public void Test2()
{
Console.WriteLine("Base");
}
}
private class Derived : Base
{
public override void Test()
{
Console.WriteLine("Derived");
}
public void Test2()
{
Console.WriteLine("Derived");
}
}
static void Main()
{
Base b = new Base();
Derived d = new Derived();
Base dInB = new Derived();
b.Test();
d.Test();
dInB.Test();
b.Test2();
d.Test2();
dInB.Test2();
Console.ReadKey(true);
}
It outputs:
Base // Base.Test()
Derived // Derived.Test()
Derived // Derived.Test()
Base // Base.Test2()
Derived // Derived.Test2()
Base // You think you're calling Derived.Test2(), but you actually call Base.Test2()
Actually this sample is invalid, because it should use the new keyword in public new void Test2() in the Derived class.
It works just like operator overloading. It doesn't actually override anything. When you have the exact type Derived it calls the new method.
You have to be really careful with hiding members, it is nothing like overriding (classes) or implementing (interfaces) at all. Only when you have the exact type it'll call a new method, otherwise it'll still call the base type's method!
The difference is that in the first case you are overriding and in the second case you are hiding which is completely different.
In the first case:
class B: A
{
void Foo()
{
B b = new B();
A a = b;
a.GetData() //B's GetData() will be called
b.GetData() //B's GetData() will be called
}
}
On the other hand in the second case:
class B: A
{
void Foo()
{
B b = new B();
A a = b;
a.GetData() //A's GetData() will be called
b.GetData() //B's GetData() will be called
}
}
In the second case you are simply hiding A's implementation of GetData() but you will always be able to call A's implementation through a variable typed A even if the variable refers to a instance of type B. Note that this is completely different from how overriding behaves.
public class A
{
public virtual string GetData() { return "A";}
}
public class B : A
{
public override string GetData() { return "B"; }
}
What do you expect if you are using the classes as in the following codeblock?
A a = new A();
B b = new B();
A c = new B();
Console.WriteLine(a.GetData());
Console.WriteLine(b.GetData());
Console.WriteLine(c.GetData());
This will print "A" "B" "B". The variable c is stored as A type but when executing the method the code is resolved to the "real" implementation. (see google for virtual function table and resolving principle)
If you do not use virtual and override as in the code below this will print "A" "B" "A".
public class A
{
public string GetData() { return "A";}
}
public class B : A
{
public new string GetData() { return "B"; }
}
Related
In the below program, since new keyword is used in the derived class, I am expecting the output "C" but am getting the output as "A". Can some one please explain the reason behind this?
Also, I would like to know how to invoke Foo method declared in the class C.
class A
{
public void Foo()
{
Console.Write("A");
}
}
class B : A
{
new void Foo()
{
Console.Write("B");
}
}
class C : B
{
new void Foo()
{
Console.Write("C");
}
}
public static void Main(string[] args)
{
C c = new C();
c.Foo();
}
C.Foo() has no visibility on the private Foo you new'ed up inside C - it will call the public derived Foo from A.
class C : B
{
public void Test()
{
// this has visibility on the private new'ed up method and can call it
this.Foo();
}
// this is just a private method - it does NOT shadow the public one
// "new" does nothing valuable here
new void Foo()
{
Console.Write("C");
}
}
public static void Main(string[] args)
{
C c = new C();
c.Foo(); // calls the public visible derived A.Foo
c.Test(); // this will call the "new"ed up C.Foo()
}
Output:
AC
You can call private methods only from inside the class they belong to - not from the outside (unless you put the call to the private one inside a public method - see Test).
Most of the time new-ing up a method (to me) is a code smell.
The keyword new in this context prevents inheritance, i.e., it hides the inherited methods instead of providing a new implementation of them. There are only rare situations where you want to do this. Mainly for static members, since those can't be overridden.
The right way to inherit and possibly override methods is to make them virtual:
class A
{
public virtual void Foo()
{
Console.Write("A");
}
}
class B : A
{
public override void Foo()
{
Console.Write("B");
}
}
class C : B
{
public override void Foo()
{
Console.Write("C");
}
}
Now, your test will work as expected. It will even work if you assign the new C to variable typed as A:
A a = new C();
a.Foo(); // Prints: C
That being said, your Foo methods in B and C don't have a public modifier and are thus private. I.e., you can only access A.Foo, which is public, from the outside.
public class Program
{
public static void Main()
{
var type = new C().getType();
type.Foo();
}
public class A
{
public void Stop()
{
// do something
}
}
public class B : A
{
public void Foo()
{
Console.WriteLine("Foo");
}
}
public class D : A
{
public void Bar()
{
Console.WriteLine("Bar");
}
}
public class C
{
public A getType()
{
if (some condition)
return new B();
if (some condition)
return new D();
return A();
}
}
}
-EDIT-
I updated the code, so now we have two child classes B and D, both have different methods inside them, however since they inherit A, they at least both have access to Stop() method. The problem with making an abstract method Foo() and Bar() inside the parent class A is that, B should not have access to Bar() and D should not have access to Foo(), but by making an abstract method they will need to implement them both.
I know that I can check the type of the returned object inside Main() method and then cast it to that type. But this won't be convenient as in the future I will have more descendants of A.
Is it in my situation ok, to use dynamic? Because that would solve the problem and would be very convenient.
public class C
{
public dynamic getType()
{
if (some condition)
return new B();
if (some condition)
return new D();
return A();
}
}
You almost had it right:
public class Program
{
public static void Main()
{
var type = new C().getType();
type.Foo();
}
public abstract class A
{
public abstract void Foo();
}
public class B : A
{
public override void Foo()
{
Console.WriteLine("Foo");
}
}
public class C
{
public A getType()
{
return new B();
}
}
}
You need a Foo method in A that B can override. I have made A.Foo abstract, which means we do not have to define a base implementation of A.Foo. The A class is declared abstract to prevent someone trying to create an instance of it.
If you want derived classes to inherit a base implementation of Foo from A, then declare Foo as virtual in A. So in the following example, class B overrides the base Foo, whereas class C inherits the base Foo:
public class Program
{
public static void Main()
{
A a1 = new B();
a1.Foo(); // Outputs "B.Foo".
A a2 = new C();
a2.Foo(); // Outputs "A.Foo".
}
public abstract class A
{
public virtual void Foo()
{
Console.WriteLine("A.Foo");
}
}
public class B : A
{
public override void Foo()
{
Console.WriteLine("B.Foo");
}
}
public class C : A
{
}
}
You are confusing the type of a variable and the type of the runtime object it will be pointing to (given its a reference type, with value types, there is no such distinction).
When you declare a variable, you are defining the type of the variable:
Foo a = ... //a is of type Foo at compile time.
What you assign to that variable doesn't matter at all (unless you are using implicitly typed variables with var)
But given the following code:
object o = new Foo();
Now you can see the diferrence; the variable o is of type object but the runtime object it will be pointing to is of type string.
In your question you are asking why you cant do the following:
var stringLength = o.Length; //o is a string isn't it?
Why? Isn't o really a string. Yes, but that information is only availabe at runtime, the compiler knows nothing of what will happen at runtime, it only knows that o is of type object and object has no Length property. The only thing the compiler will make sure of is that the types are compatible; it will let you assign a Giraffe to an Animal typed variable but it won't let you assing a Car.
If you've got this clear, then you'll understando why this doesn't make sense:
But I did explicitly return B inside getType() method, why does it not have access to Foo()?
Because the method getType return type is A not B, not C and not D.
I have C# code, base class A and derived class B:
public class A
{
public virtual void print() {Console.WriteLine("a"); }
}
public class B:A
{
public override void print() { Console.WriteLine("b"); }
}
static void Main(string[] args)
{
A a= new B();
//In c++ I can use .Base:: to call base method from derived class instance
a.Base::print();
}
I can't modify these two classes and I don't know what can I do in C#, any suggestion?
Additionally, thanks to everyone joining into this discussion, and I would like to clarify why I need this behavior:
In .net framework, we have an interface IPostBackDataHandler to handle postback. and in there is a method
public bool LoadPostData( string postDataKey, NameValueCollection postCollection )
When I implement it and test, I find sometimes the given postback type of postCollection is NameValueCollection ,while other time it's HttpValueCollection (a derived class of NameValueCollection)
Then,if it is a type of HttpValueCollection, when I get item from it, eg. postCollection['ControlID'] and I input html in this control, HttpValueCollection.get_item() will always validate the input and view it as a defect. While NameValueCollection.get_item() won't
I don't want it operate validation automatically, at least I should decide whether it should be validated, should I?
There is no way to access base method from outside the derived class.
You can either write a method in derived class that will call base method like this:
public class B : A
{
public override void print() { Console.WriteLine("B"); }
public void basePrint() { base.print(); }
}
Or you can user Reflection to get base method definition and invoke it but it's rather ugly.
Here is how to create DynamicMethod that calls base print method:
// Get MethodInfo of the base method
var methodInfo = typeof(A).GetMethod("Print", BindingFlags.Instance | BindingFlags.Public);
// Create DynamicMethod based on the methodInfo
var dynamicMethod = new DynamicMethod("BasePrint", methodInfo.ReturnType, new[] { methodInfo.DeclaringType }, methodInfo.DeclaringType);
// Create ILGenerator for the dynamic method
var il = dynamicMethod.GetILGenerator();
// Emit argument with index 0 - DeclaringType
il.Emit(OpCodes.Ldarg_0);
// Emit method call
il.EmitCall(OpCodes.Call, methodInfo, null);
// Emit method return value
il.Emit(OpCodes.Ret);
// Invoke method with target...
var b = new B();
dynamicMethod.Invoke(null, new object[] {b});
// ... or create a delegate and invoke method without target
var action = dynamicMethod.CreateDelegate(typeof(Action)) as Action;
action.Invoke();
Note that it'll work only for parameterless method. If you want to call method with parameters you'll have to put their types into the array with the DeclaringType and later emit all of them. Also you'll have to create delegate of type Action<parameterTypes or Func<returnType, parameterTypes> if the method returns something.
You can only call your base class's methods from the derived class (B) by doing:
base.print();
I don't think there is a way to do what you want to do, because it kind of breaks the point of polymorphism.
However, you can hide the print method in A by doing this in B:
new public void print() { Console.WriteLine("b"); }
This way, this code:
A a= new B();
a.print();
will call the print in A.
Thanks to everyone!
Finally I realize this behavior need using reflection and delegate, like nocodename showing, here I find a similar method.
A a = new B();
var ptr = typeof(A).GetMethod("Print", new[] { typeof(_inputParameter) }).MethodHandle.GetFunctionPointer();
var baseGetItem = (Func<String, String>)Activator.CreateInstance(typeof(Func<String, String>), a, ptr);
String postedValue = baseGetItem(_parameter);
You can't call base print outside of a class B i.e. from Main method due to way how override works in c#. However if you want to have possibility to do that, you should consider to shadow print method in class B:
public class B:A
{
public new void print() { Console.WriteLine("b"); }
}
With new keyword class shadows member from parent class, so your line of code will work:
A a= new B();
a.print(); //prints "a"
and
B b= new B();
b.print(); //prints "b"
The whole idea of override is that you will not call the base class's function.
If you want to call A.print - use A object, if you want to call B.print use B object, and if you want an object that can use some of that and some of that - create it separately or use functions with different names, that might solve your problem.
I'm not sure what you are trying to accomplish here, but maybe you would like to read about Visitor Pattern
Good Luck!
You can simply call base class method from derived class by using "base" keywork:
see example,
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
B obj= new B();
obj.print();
Console.ReadKey();
}
}
public class A
{
public virtual void print() { Console.WriteLine("a"); }
}
public class B : A
{
public override void print()
{
base.print();
Console.WriteLine("b");
}
}
}
hope you understand! Thank u
You cannot call the base method when you override it in the inherited. You can make the method in B to be new instead of override, but you lose the implementation.
public class A
{
public virtual void Print() { Console.WriteLine("a"); }
}
public class B: A
{
public new void Print() { Console.WriteLine("b"); }
}
This way when you call
static void Main(string[] args)
{
A a = new B();
a.Print(); // prints "a"
}
Otherwise, you can call base.Print() in the overridden method.
public class A
{
public virtual void Print() { Console.WriteLine("a"); }
}
public class B: A
{
public override void Print()
{
base.Print();
Console.WriteLine("b");
}
}
var obj = new B();
obj.Print(); // overriden method
(obj as A).Print(); // base method
I'm confused with the following scenario, we have a set of classes like this
public class A
{
public virtual string SomeMethod()
{
return "A";
}
}
public class B : A
{
public override string SomeMethod()
{
return "B";
}
}
public class C : B
{
public new virtual string SomeMethod()
{
return "C";
}
}
public class D : C
{
public override string SomeMethod()
{
return "D";
}
}
When i call the following method
private void Test()
{
A a = new D();
B b = new D();
C c = new D();
D d = new D();
Console.WriteLine(a.SomeMethod()); //The method in class B is being called
Console.WriteLine(b.SomeMethod()); //The method in class B is being called
Console.WriteLine(c.SomeMethod()); //The method in class D is being called
Console.WriteLine(d.SomeMethod()); //The method in class D is being called
}
I'm getting the output like this
B B D D
Why is it that the inherited method is being called, instead of the method in the declared type, and why isn't the method in class D being called every time?
When you call SomeMethod on an instance of A (i.e. A foo = new <A or derived>()), you expect to get the most derived version of SomeMethod available. That's the whole point of inheritance. Your code only needs to deal with instances of the base class, but if those instances happen to really be of a derived class, the special dervied implementations are invoked. This is the behavior you get when you override a method.
This explains common scenarios like
A b = new B();
b.SomeMethod(); // B's implementation invoked
With new, you are not overriding the method, you are declaring a brand new method with the same name. This method exists only on the class that declared it and its children, it's not part of the base classes and their inheritance chain.
So what does A a = new D(); a.SomeMethod(); do? The variable is declared as A, so any methods/properties/etc invoked against it have to be defined on A. C defined a new method SomeMethod (and D overrides it), but this method doesn't exist on A, so it cannot be invoked here. The most derived implementation of SomeMethod (as declared on type A) is in B, so this is the implementation which is invoked.
Same story for B b = new D(); b.SomeMethod();
It's only when we get to C c = new D(); c.SomeMethod() that the new method has a chance to execute. This is because the variable is a C, and thus the new method SomeMethod is for the first time declared on the variable type. And as stated above, the most derived possible version will be invoked, which in this case means the version overriden by D.
And I hope we are all on the same page for D d = new D(); d.SomeMethod() :)
Others have posted good links. Here's another thread that might help: C# and method hiding
And the last example here shows an even weirder scenario where the "new" method is declared as private, thus a further dervied type actually inherits the base version of the method, rather than inheriting the "new" version. http://msdn.microsoft.com/en-us/library/aa691135
I try to explain it in a different way.
virtual / override means, that you implement / change the behaviour of the same method. It is an implementation of polymorphism. With new, you create a completely new method. It happens to have the same signature as another method, but doesn't have anything to do with it.
When calling this methods, it depends on which type the reference has (compile time type), to choose the method you actually call.
Your code is equivalent to:
public class A
{
public virtual string SomeMethod()
{
return "A";
}
}
public class B : A
{
public override string SomeMethod()
{
return "B";
}
}
public class C : B
{
public virtual string AnotherMethod()
{
return "C";
}
}
public class D : C
{
public override string AnotherMethod()
{
return "D";
}
}
private void Test()
{
A a = new D();
B b = new D();
C c = new D();
D d = new D();
Console.WriteLine(a.SomeMethod()); //The method in class B is being called
Console.WriteLine(b.SomeMethod()); //The method in class B is being called
Console.WriteLine(c.AnotherMethod()); //The method in class D is being called
Console.WriteLine(d.AnotherMethod()); //The method in class D is being called
}
The compiler chooses to call AnotherMethod for reference of type C (and D).
That is a well-known behavior: when you hide method (with new) it is called only when you are accessing it through instance of hiding type; when you use instance of base class, original method is used.
Hiding is not overriding.
I'm trying to override an overridden method (if that makes sense!) in C#.
I have a scenario similar to the below, but when I have a breakpoint in the SampleMethod() in the "C" class it's not being hit, whilst the same breakpoint in the "B" method is being hit.
public class A
{
protected virtual void SampleMethod() {}
}
public class B : A
{
protected override void SampleMethod()
{
base.SampleMethod();
}
}
public class C : B
{
protected override void SampleMethod()
{
base.SampleMethod();
}
}
Thanks in advance!
Edit:
Ok, the context would help:
This is in the context of a composite control so class A inherits from CompositeControl and calls SampleMethod() after overriding the CreateChildControls() method.
Overriding can be performed in a chain as long as you like. The code you have shown is correct.
The only possible explanation for the behaviour you are seeing is that the object to which you are referring is actually of type B. I suggest that you double check this, and if things still don't make sense, post the other appropiate code.
Without seeing the code that calls SampleMethod, my guess would be that you have an object of type B and call SampleMethod on that.
The breakpoint is more than likely not being hit because you actually instantiated an instance of the "B" class.
Method override resolution works based on the actual runtime type of the class whose method should be called. So, if you had the following code:
C c = new C();
c.SampleMethod();
and the following:
C c = new C();
B b = (B)c;
b.SampleMethod();
both the runtime types of the class whose SampleMethod will be called is type B.
That solution works fine; although to actually use it outside the class the method is in, you need to set the access of SampleMethod to public rather than protected in all of the cases it appears, so:
public class A
{
public virtual void SampleMethod()
{
Console.WriteLine("lol");
}
}
public class B : A
{
public override void SampleMethod()
{
base.SampleMethod();
}
}
public class C : B
{
public override void SampleMethod()
{
base.SampleMethod();
}
}
for Overriding more than once in the hierarchy use something like this
// abstract class
abstract class A
{
public abstract void MethodOne();
}
// class B inherits A
class B : A
{
public override void MethodOne()
{
Console.WriteLine("From Class B");
}
}
// class C inherits B
class C : B
{
public override void MethodOne()
{
Console.WriteLine("From Class C");
}
}
// class D inherits C
class D : C
{
public override void MethodOne()
{
Console.WriteLine("From Class D");
}
}
// etc......
// class Main method Class
class MainClass
{
public static void Main()
{
B[] TestArray = new B[3];
B b1 = new B();
C c1 = new C();
D d1 = new D();
TestArray[0] = b1;
TestArray[1] = c1;
TestArray[2] = d1;
for (int i = 0; i < TestArray.Length; i++)
{
TestArray[i].MethodOne();
}
Console.ReadLine();
}
}
I did it in this code in this link
http://www.4shared.com/rar/0SG0Rklxce/OverridingMoeThanOnce.html
Method overriding is OOP feature that allows a child class to provide a specific implementation of a method that is already provided by one of its parent classes.