why need to use virtual and override? - c#

i have created same name methods in base and derived classes and i am able to create
class Program
{
public void CalculateArea(int a,int b)
{
Console.WriteLine(a*b);
}
}
class progrmm1:Program
{
public void CalculateArea(int a ,int b)
{
Console.WriteLine(a + b);
}
static void Main(string[] args)
{
progrmm1 obj = new progrmm1();
Program obj1 = new Program();
obj.CalculateArea(4,5);
obj1.CalculateArea(4,5);
Console.ReadLine();
}
}
then why i need to use virtual and override

If you don't use virtual and override then you are not taking advantage of polymorphism. Basically the CalculateArea in the derived class is hiding the one in the base class. That means that if you reference an object of the derived class type as the base it will call the CalculateArea in the base class instead of the derived one. Where as if you use virtual and override it would call the Derived method even if it where referenced as the Base.
For example with these classes
public class Base
{
public void DoSomething()
{
Console.WriteLine("Base.DoSomething");
}
}
public class Derived : Base
{
public void DoSomething()
{
Console.WriteLine("Derived.DoSomething");
}
}
This code
Base derivedAsBase = new Derived();
derivedAsBase.DoSomething();
will output
Base.DoSomething
but using virtual and override
public class Base
{
public virtual void DoSomething()
{
Console.WriteLine("Base.DoSomething");
}
}
public class Derived : Base
{
public override void DoSomething()
{
Console.WriteLine("Derived.DoSomething");
}
}
The same code
Base derivedAsBase = new Derived();
derivedAsBase.DoSomething();
will output
Derived.DoSomething

When overridden, the method on the most derived class is called. Observe this slightly modified code where I assign two Program instances. One from a Program and one from a program1:
class Program
{
public virtual void CalculateArea(int a, int b)
{
Console.WriteLine(a * b);
}
}
class progrmm1 : Program
{
public override void CalculateArea(int a, int b)
{
Console.WriteLine(a + b);
}
static void Main(string[] args)
{
Program obj = new progrmm1();
Program obj1 = new Program();
obj.CalculateArea(4, 5);
obj1.CalculateArea(4, 5);
Console.ReadLine();
}
}
OUTPUT:
9
20
And now, observe non-virtual:
class Program
{
public void CalculateArea(int a, int b)
{
Console.WriteLine(a * b);
}
}
class progrmm1 : Program
{
public void CalculateArea(int a, int b)
{
Console.WriteLine(a + b);
}
static void Main(string[] args)
{
Program obj = new progrmm1();
Program obj1 = new Program();
obj.CalculateArea(4, 5);
obj1.CalculateArea(4, 5);
Console.ReadLine();
}
}
OUTPUT
20
20

First you need to know about Virtual Method.
Basically A virtual method is a method that can be redefined in
derived classes. A virtual method has an implementation in a base
class as well as derived the class.
Example:
Let Suppose we have two classes, A and B. Class A has a public virtual method called Test. Class B, meanwhile, derives from class A and it provides a public override method called Test as well.
using System;
class A
{
public virtual void Test()
{
Console.WriteLine("A.Test");
}
}
class B : A
{
public override void Test()
{
Console.WriteLine("B.Test");
}
}
class Program
{
static void Main()
{
// Compile-time type is A.
// Runtime type is A as well.
A ref1 = new A();
ref1.Test();
// Compile-time type is A.
// Runtime type is B.
A ref2 = new B();
ref2.Test();
}
}
Output
A.Test
B.Test
Why would you need to use virtual methods?:
Your program may be designed in such a way that you do not know all the types of objects that will occur when it is executed. You can provide a standard (base) type and design around that type.
Then, you can re-implement important functionality depending on the more specific (derived) types. When you call a method on the base type, you invoke the more derived (and useful) method.

Related

"CS0109: The member 'member' does not hide an inherited member. The new keyword is not required" - is this actually true?

I've read other threads and Eric Lippert's posts on the subject, but haven't seen this exact situation addressed anywhere.
C# optional parameters on overridden methods
Optional parameters and inheritance
I'm trying to implement the following situation:
public class BaseClass
{//ignore rest of class for now
public void DoThings(String str)
{
//dostuff
}
}
public class DerivedClass: BaseClass
{//ignore rest of class for now
new public void DoThings(String str, Int32 someint = 1)
{
//dostuff but including someint, calls base:DoThings in here
}
}
When I do this the compiler gives me the warning in the subject line that I do not need to use the new keyword because the method does not hide the inherited method. However I do not see a way to call the base method from the object instance, so it looks hidden to me.
I want it to actually be hidden. If it is not hidden, there is potential for some other user to some day call the base method directly and break the class (it involves thread safety).
My question is, does the new method actually hide the inherited method (compiler is wrong?) or is the compiler correct and I need to do something else to hide the original method? Or is it just not possible to achieve the desired outcome?
void DoThings(String str) accepts a single parameter
void DoThings(String str, Int32 someint = 1) accepts two parameters
=> the methods are distinct, unrelated methods, which incidentally share the name.
Default parameters are inserted at the call-sites during compilation.
Here is one possible solution:
public class BaseClass
{
public virtual void DoThings(String str)
{
//dostuff
}
}
public class DerivedClass: BaseClass
{
public override void DoThings(String str)
{
DoThings(str, 1); // delegate with default param
}
public void DoThings(String str, Int32 someint)
{
//dostuff
}
}
Note that new makes it possible to call base classes' virtual methods in the first place by having a reference with static type of the base class (e.g. by casting it to the base class):
public class Test
{
public static void Main()
{
var obj = new DerivedClass();
BaseClass baseObj = obj;
obj.DoThings("a");
baseObj.DoThings("b");
((BaseClass)obj).DoThings("c");
}
}
class BaseClass
{
public void DoThings(String str)
{
Console.WriteLine("base: " + str);
}
}
class DerivedClass: BaseClass
{
new public void DoThings(String str, Int32 someint = 1)
{
Console.WriteLine("derived: " + str);
base.DoThings(str);
}
}
Output:
derived: a
base: a
base: b
base: c
If you want callers to never call the overridden method of a base class, mark it virtual and override it (like already shown at the top of this answer):
public class Test
{
public static void Main()
{
var obj = new DerivedClass();
BaseClass baseObj = obj;
obj.DoThings("a");
baseObj.DoThings("b");
((BaseClass)obj).DoThings("c");
}
}
class BaseClass
{
public virtual void DoThings(String str)
{
Console.WriteLine("base: " + str);
}
}
class DerivedClass: BaseClass
{
// "hide" (override) your base method:
public override void DoThings(String str)
{
// delegate to method with default param:
this.DoThings(str);
}
public void DoThings(String str, Int32 someint = 1)
{
Console.WriteLine("derived: " + str);
base.DoThings(str);
}
}
Output:
derived: a
base: a
derived: b
base: b
derived: c
base: c
After discussion in the comments: you do not want to use inheratince here, but rather opt for compisition.
The code could look like the following:
public class Test
{
public static void Main()
{
var obj = new DerivedClass(new BaseClass());
obj.DoThings("a");
// baseObj.DoThings("b"); // not accessible
// ((BaseClass)obj).DoThings("c"); // InvalidCastException!
}
}
class BaseClass
{
public void DoThings(String str)
{
Console.WriteLine("base: " + str);
}
}
class Wrapper
{
private BaseClass original;
public Wrapper(BaseClass original) {
this.original = original;
}
public void DoThings(String str, Int32 someint = 1)
{
Console.WriteLine("wrapped: " + str);
original.DoThings(str);
}
}
Output:
base: a
wrapped: a
the 'new' keyword can't be used where you used it
To hide the member:
public class BaseClass
{ // ignore rest of class for now
public virtual void DoThings(String str)
{
// dostuff
}
}
public class DerivedClass: BaseClass
{ //ignore rest of class for now
public override void DoThings(String str)
{
// dostuff
}
public void DoThings(String str, Int32 someint = 1)
{
// do stuff but including some int, calls base:DoThings in here
}
}

Pattern to avoid the need for Downcasting/Reflection

Suppose I have two implementations of a base class:
public class Base {
public string Stringify() { return "I am a member of base class"; }
}
public class A : Base {
public void DoAThing() {...};
}
public class B : Base {
public void DoBThing(int anInteger) {...};
}
Suppose I want to put many instances of Base in a list, so that I can loop over them and call Stringify() on each, and make use of their shared functionality.
static void Main(string[] args)
{
A thing1 = new A();
B thing2 = new B();
B thing3 = new B();
List<Base> list = new List<Base> {thing1, thing2, thing3};
foreach(Base base in list) { Console.WriteLine(base.Stringify()); }
}
Now suppose there are many many Base objects, such that maintaining the individual thing references to each one is not realistic. Would there be any way, via only the list, to regain the DoAThing() or DoBThing() functionality that is lost by the abstraction without having to use explicit downcasting and reflection?
This feels like it would be a common enough occurance, so I am wondering if there is a design flaw or established pattern I am missing here that would help in this situation.
If you debug, you can notice every object of the list mantains its' class.
This way:
class Program
{
static void Main(string[] args)
{
A thing1 = new A();
B thing2 = new B();
B thing3 = new B();
List<Base> list = new List<Base> { thing1, thing2, thing3 };
foreach (Base bas in list) {
Console.WriteLine(bas.Stringify());
if(bas is A)
{
((A)bas).DoAThing();
}
else if (bas is B)
{
((B)bas).DoBThing(1);
}
else
{
//IDK
}
}
}
}
public abstract class Base
{
public string Stringify() { return "I am a member of base class"; }
}
public class A : Base
{
public void DoAThing()
{
}
}
public class B : Base
{
public void DoBThing(int anInteger)
{
}
}

How use IInterceptor in Castle.DynamicProxy?

I wrote an example like this
Simple Calculator class :
public class Calculator
{
public int Add(int a, int b)
{
return a + b;
}
}
implemented "IInterceptor" that provided by DynamicProxy
[Serializable]
public abstract class Interceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
ExecuteBefore(invocation);
invocation.Proceed();
ExecuteAfter(invocation);
}
protected abstract void ExecuteAfter(IInvocation invocation);
protected abstract void ExecuteBefore(IInvocation invocation);
}
Created an Interceptor class and inherited from "Interceptor" class
public class CalculatorInterceptor : Interceptor
{
protected override void ExecuteBefore(Castle.DynamicProxy.IInvocation invocation)
{
Console.WriteLine("Start");
}
protected override void ExecuteAfter(Castle.DynamicProxy.IInvocation invocation)
{
Console.WriteLine("End");
}
}
but when I used it NOT working !!!
static void Main(string[] args)
{
ProxyGenerator generator = new ProxyGenerator();
Calculator c = generator.CreateClassProxy<Calculator>(new CalculatorInterceptor());
var r = c.Add(11, 22);
Console.WriteLine(r);
Console.ReadKey();
}
I excepted to see something like this :
START
33
END
but only show
33
How I can correct it ?!
Try to make the method Add virtual.
public class Calculator
{
public virtual int Add(int a, int b)
{
return a + b;
}
}
The proxy generator creates a new class inheriting Calculator. Thus, the method Add gets an override to make interception possible.
The other option is to make an ICalculator interface
public interface ICalculator
{
int Add(int a, int b);
}
and inherit your class from this interface
public class Calculator : ICalculator
{
public int Add(int a, int b)
{
return a + b;
}
}
Your dynamic proxy would then use the CreateInterfaceProxyWithTarget method
var proxyGenerator = new ProxyGenerator();
ICalculator calculator = new Calculator()
var proxy = proxyGenerator.CreateInterfaceProxyWithTarget(
calculator,
ProxyGenerationOptions.Default,
new CalculatorInterceptor());
Console.WriteLine(proxy.Add(1, 2));
This gets rid of the virtual from your Calculator class, which in my opinion is bad design unless you have reason to override the method in the future.
You have to use the correct overload and pass in both the target object and the interceptor you wish to use. Method should look something like this:
var proxy = generator.CreateClassProxy<Calculator>(new Calculator(), new CalculatorInterceptor() );

Function overriding without virtual and override

I just have one basic question :
public class virtualTest
{
public virtual void vTest()
{
Console.WriteLine("Base Class");
}
}
public class derivedVirtualTest : virtualTest
{
public override void vTest()
{
Console.WriteLine("Derived Class");
}
}
Here i have used function overriding with function vTest()
But if i :
public class virtualTest
{
public void vTest()
{
Console.WriteLine("Base Class");
}
}
public class derivedVirtualTest : virtualTest
{
public void vTest()
{
Console.WriteLine("Derived Class");
}
}
removes virtual and override keywords from respective places , then also code works.
How can this be possible?
Or then what is the use of override and virtual (entire function overriding) if code works fine without virtual and override???
EDIt:
My Method through which i am calling above classes
static void Main(string[] args)
{
derivedVirtualTest objderivedVirtualTest = new derivedVirtualTest();
objderivedVirtualTest.vTest();
virtualTest objvirtualTest = new virtualTest();
objvirtualTest.vTest();
Console.ReadLine();
}
As qwr explained, the main difference in terms of OOP is polymorphism. It means that if you access the class which overrides the base member through a base type reference, the call you perform to the overriddable member is redirected to the override.
In case of a class which shadows/hides the base member, the call is not redirected, and the base class' method is being executed.
So, given:
class Base
{
public virtual void OverrideMe()
{
Console.WriteLine("I'm the base");
}
}
class Derived : Base
{
public override void OverrideMe()
{
Console.WriteLine("I'm derived");
}
}
class Shadowing : Base
{
public void OverrideMe()
{
Console.WriteLine("I'm shadowing");
}
}
And using them this way:
var instances = new Base[] {new Base(), new Derived(), new Shadowing()};
foreach (var instance in instances)
{
instance.OverrideMe();
}
Will produce:
I'm the base
I'm derived
I'm the base
Additional difference is that in case of overriding you can evolve your base class, like changing the signature of the base member or removing it completely, without changing the hiding one. Which in some cases may suit needs exactly and in some - not so much.
In case of overriding you must change the signature of overriding member as well, otherwise your code will fail to compile.
In the second example, maybe you test your code like this:
derivedVirtualTest deviTest = new derivedVirtualTest();
deviTest.vTest(); //Result "Derived Class"
Try this, and you'll see that the function has't been overridden yet:
virtualTest deviTest = new derivedVirtualTest();
deviTest.vTest(); //Result "Base Class"
//This will result "Dervived class" in the first one
It will be needed when your sealed method overriding a method
public class Animal{
public virtual void eat() { Console.WriteLine("eating..."); }
public virtual void run() { Console.WriteLine("running..."); }
}
public class Dog: Animal
{
public override void eat() { Console.WriteLine("eating bread..."); }
public sealed override void run() { //If you skipped override here it will throws an error
Console.WriteLine("running very fast...");
}
}
public class TestSealed
{
public static void Main()
{
BabyDog d = new BabyDog();
d.eat();
d.run();
}
}

while overidding base methods, why default arguments are not working well? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
C# optional parameters on overridden methods
using System;
namespace Apple
{
class A
{
public virtual void Func(int a=4){
Console.WriteLine(" A Class: "+a);
}
}
class B : A
{
public override void Func(int a = 12)
{
Console.WriteLine(" B Class: "+ a);
}
}
public class Program
{
static void Main(string[] args)
{
A ob = new B();
ob.Func();
Console.ReadLine();
}
}
}
// Output: B Class: 4
Default parameters are filled at compile time, and the code references a variable ob through the base class. The virtual method override works at run time, as expected. You could achieve the desired effect by using method overload:
class A
{
public void Func(int value)
{
}
public virtual void Func()
{
Func(4);
}
}
class B: A
{
public override void Func()
{
Func(12);
}
}
The compiler places the the default parameter value based on the type of the object and is done during the compile time.
Hence the compiled code would look like:
using System;
namespace Apple
{
public class Program
{
private static void Main(string[] args)
{
A ob = new B();
ob.Func(4);
Console.ReadLine();
}
}
}
You could get the desired result by doing this:
public class Program
{
static void Main(string[] args)
{
A ob = new B();
((B)ob).Func();
Console.ReadLine();
}
}
Because you creating instance of Class A which is referring to the address of class B.
A ob = new B();
Since the instance is of class A, the method you calling is pointing to method in class A.
You can check this by putting debug and then execute the code.
instead if you create instance of class B ie
B ob = new B();
it will call the method Fun() from class B and will display output as
" B Class: 12"
the default parameter value is Static binding.

Categories