accessing overridden method from derived class object - c#

Is it possible to access the method that has been overridden using the object of the derived class?
using System;
class Bclass
{
public virtual int result(int a,int b)
{
return a + b;
}
}
class Dclass:Bclass
{
public override int result(int a, int b)
{
return a - b;
}
}
public class Program
{
static public void Main(string[] args)
{
Dclass obj1 = new Dclass();
Console.WriteLine(obj1.result(10, 5));
}
}
Is there a way to get the output as 15?

From MSDN documentation:
The override modifier is required to extend or modify the abstract or
virtual implementation of an inherited method, property, indexer, or
event.
override modifier are designed to extend functionality of virtual function. When ever you call overridden function with the help of derived class object it will call overridden function.
To answer your question,
Is it possible to access the method that has been overridden using the
object of the derived class?
There is no way to call virtual method directly using derived class object
Ways to call virtual method:
Approach 1:
Create a new function in derived class and call base.result() from it.
public int BaseResult(int a, int b)
{
return base.result(a, b);
}
and call BaseResult() using derived class instance
Dclass obj1 = new Dclass();
Console.WriteLine(obj1.BaseResult(10, 5));
Try it online
Approach 2:
Create instance of base class and from that access virtual method.
Bclass obj2 = new Bclass();
Console.WriteLine(obj2.result(10, 5));

Unless you need to declare the base method as virtual for some reason, you could also achieve what you want by declaring the derived class method as new, thereby hiding the implementation when using it through an instance of the derived class.
At the same time, you can still access the base implementation by casting the object to the base class.
Following the example you provided:
class Bclass
{
public int result(int a,int b)
{
return a + b;
}
}
class Dclass : Bclass
{
public new int result(int a, int b)
{
return a - b;
}
public int BaseResult(int a, int b)
{
return base.result(a, b);
}
}
public class Program
{
public static void Main(string[] args)
{
Dclass obj1 = new Dclass();
Console.WriteLine(((Bclass)obj1).result(10, 5)); // 15
}
}
More information about the differences between override and new can be found in this MSDN article.

Related

How to process data including protected members using extension method in C#

Recently, I had a need to process the private data contained in the base class using the methods of the child class. My base class could only contain domain-specific types (it only represents data). So first I decided to create a child-class in another project and implement the processing logic in it. But the problem is that once you create an instance of the base class, you can't cast it to the child type:
public class A
{
protected int member1;
public A(int value)
{
member1 = value;
}
}
public class B : A
{
public B (int value) : base(value)
{ }
public void DoSomething()
{
Console.Write(member1 * member1);
}
}
class Program
{
static void Main(string[] args)
{
A obj1 = new A(5);
B obj2 = (B)obj1; // InvalidCastException
obj2.DoSomething();
}
}
And I started thinking towards extension methods. However, you can't just access the protected fields of the class from them. In the end, I tried to combine the two approaches.
Here's my solution:
Make sure that you are allowed to add new methods to your base class and that your class is not sealed.
Add protected static method which returns the protected member you need.
Create an Extension class for your base class.
In extension class create a private nested class.
Inherit your nested class from your base class.
Create static method in nested class and implement the processing logic in (you can call static protected method from base class to get protected member from base class).
Create extension method in extension class and call static method of nested class in it.
The sample code is shown below:
public class A
{
protected int member1 = 0;
public A() {}
public A(int value)
{
member1 = value;
}
protected static int GetProtectedMember(A objA)
{
return objA.member1;
}
}
public static class AExtensions
{
public static void DoSomething(this A objA)
{
B.DoSomething(objA);
}
private class B : A
{
public static void DoSomething(A objA)
{
// objA.member1 // it's not allowed
int protectedFromA = A.GetProtectedMember(objA);
int sqr = protectedFromA * protectedFromA;
Console.WriteLine(sqr);
}
}
}
class Program
{
static void Main(string[] args)
{
A obj1 = new A(5);
obj1.DoSomething(); // 25
}
}
This way you can keep the classes that represent the data in a separate project and have multiple implementations of processing this data in different projects.

Override at least one method

Let's suppose there is a following class:
public class foo{
internal virtual object M1(/*args*/){return null;}
internal virtual object[] M2(/*args*/){return null;}
public SomeStruct SomeMethod(){
return new SomeStruct
{
Obj = M1();
ObjArr = M2();
}
}
}
Using the following struct:
public class SomeStruct
{
public object Obj;
public object[] ObjArr;
}
Is there a way to make sure (preferably at compilation) to force either at least one method or exactly one method of class foo to be overriden?
Before anybody says it - I know it's possible to use one method and check if the result is array (or IEnumerable) and then assign it to the right field, but that takes more time then just running empty methods. I'm just wondering if it's possible to do it that way.
You could mark the methods abstract, and then you will be forced to implement both of the methods. This seems to be the most straightforward solution:
internal abstract object M1(/*args*/){return null;}
internal abstract object[] M2(/*args*/){return null;}
Another option, actually too complicated for this purpose, is to write a Roslyn code analyzer which will check the code and determines if it is valid.
As a side note: your fields should reside in the base class too. You could use generics if you want to make the types of them generic.
"No", basically. At least, not without writing your own custom code analyzer (perhaps via Roslyn), and considering what happens if X : foo overrides M1, and Y : X overrides M2.
You need to create a new method in your child class that hides the implementation of the base class, with the new return type. You cannot use virtual methods to overload a method like you're doing.Overloading of methods is done by changing the parameters, not the return type.
So either hide the parent method, in the child class, or create a method with another name.
Here is something that I can think of, just an example.
Run it here .Net Fiddle
using System;
public class a
{
public virtual object s(int a)
{
return a + 1;
}
}
public class b : a
{
public virtual object[] s(int a)
{
var arr = new object[]{a + 2};
return arr;
}
}
public class c : b
{
private a A = new a();
private b B = new b();
public c()
{
print(2);
}
public void print(int a)
{
var result = A.s(1);
Console.WriteLine("result : " + result);
var resultB = B.s(1);
//or resultB = base.s(1);
foreach (var r in resultB)
{
Console.WriteLine("result B : " + r);
}
}
}
public class Program
{
public static void Main()
{
c C = new c();
}
}

can we call method M1 for abstract class A?

experts,
below is code for abstract class with virtual method and override in class B.
Can we call method M1 of class A, as we can't instantiate this? thanks,
public abstract class A
{
public virtual int M1(int a, int b)
{
return a + b;
}
}
public class B : A
{
public override int M1(int a, int b)
{
return a - b;
}
}
As soon as B overrides M1 virtual method dispatch will make B.M1() being called, even when you cast instance of B to A.
The only place you can call it is from within B code, using base.M1() syntax:
public override int M1(int a, int b)
{
var temp = base.M1(a, b);
return temp - a - b;
}
However, there can be another class inheriting from A (lets name it C), which does not override M1. In that case, calling M1 on instance of C will invoke A.M1().
You must instantiate a class that implements A1, virtual is a method you CAN override but if you don't it will execute the base class method.

Class constructor error

Since we know that constructor is not inherited in the child class as i asked in the my previous question Click here to view question
I had write the code
namespace TestConscoleApplication
{
abstract public class A
{
public int c;
public int d;
private A(int a, int b)
{
c = a;
d = b;
}
public virtual void Display1()
{
Console.WriteLine("{0}{1}", c, d);
}
}
internal class B : A
{
protected string Msg;
public B(string Err)
{
Msg = Err;
}
public void Display()
{
Console.WriteLine(Msg);
}
}
class Program
{
static void Main(string[] args)
{
B ObjB = new B("Hello");
Console.ReadLine();
}
}
}
when i compile the code its showing an error
Error TestConscoleApplication.A.A(int, int) is inaccessible due to its protection level.
Then why it is showing an error.
By making the only constructor of A private, you've prevented derived classes from being able to be constructed outside A.
Derived class constructor always call the base constructor (one of). Making it private you prohibit access to it from outside. In other words you make it impossible to make an instance of A outside A.
Since you made a constructor, the compiler won't generate a default public one for this class for you.
If you want to provide access to it from the class descendant but not from outside, you should make it protected.
You need to have a constructor for A accessible to B, and use it. Also, the default base constructor is base() (i.e. the parameterless constructor), which doesn't exist on A. Here's one way you can resolve this (nonessential bits removed):
abstract public class A
{
protected A(int a, int b)
{
}
}
internal class B : A
{
public B(int a, int b, string Err)
: base(a, b)
{
}
}
constructors shouldn't be private otherwise you will not be able to create an instance of that class and won't be able to inherit it too, but if you want to create a private constructor create a public one with it too.
For more info Go here

C# subtype casted to super type but still want the subtype method called

I'm wondering if the following is possible:
class A
{
public int SomeMethod()
{
return 1;
}
}
class B : A
{
public override int SomeMethod()
{
return 3;
}
}
class DrivingClass
{
public static void Main()
{
B classB = new B();
A classA = (A)classB;
Assert.IsEqual(3, classA.SomeMethod());
}
}
This fails of course expecting 3 but actual is 1. Is there a way (without typecasting it back to B) for classA.SomeMethod() to call the overridden version since it started out as B(although I assume this knowledge is lost once casted).
UPDATE:
Class A is already written and for all intents and purposes can not be edited. I can only control class B. Knowing the class B will be casted to type A, I simply want my implementation to be used when SomeMethod() is called on my typecasted B.
SomeMethod needs to be declared as virtual in A in order to successfully override it in B.
public virtual int SomeMethod() // in A
public override int SomeMethod() // in B
With this properly in place
A a = new B();
int value = a.SomeMethod();
Debug.Assert(value == 3); // succeeds
If you instead have
public int SomeMethod() // in A
public new int SomeMethod() // in B, or just
public int SomeMethod() // in B
Then the above assertion fails. The method in B hides the base method, but only via the B reference. When operating under the reference of A, you get the base behaviors.
A a = new B();
int value = a.SomeMethod(); // gets 1 from A, not 3 from B
UPDATE: Class A is already written and for all intents and purposes can not be edited. I can only control class B. Knowing the class B will be casted to type A, I simply want my implementation to be used when SomeMethod() is called on my typecasted B.
Methods are not virtual by default in C#. If the authors of A did not design it with extensibility in mind (at least, as far as overriding SomeMethod), you will not be able to replace or override that behavior with B when it is being treated as A. However, if you are in a position to control the casting, or rather the dependency of the code, you can perhaps invert it so that A actually adheres to the contract of B, not the other way around. Consider the Adapter Pattern, for example.
interface IB
{
int SomeMethod();
}
class B : IB
{
public int SomeMethod() { return 3; }
}
class ABAdapter : IB
{
private A a;
public ABAdapter(A a) { this.a = a; }
public int SomeMethod() { return a.SomeMethod(); }
}
In this example, you've used the adapter to pattern to make A actually fulfill the contract of B, via the IB interface. So code that might once have depended upon A or B can now depend upon IB. The ABAdapter simply delegates to the A implementation.
public void DoSomething(IB ib) // given
A a = new A();
DoSomething(new ABAdapter(a)); // invoke with A
DoSomething(new B()); // invoke with B
You haven't declared SomeMethod to be virtual in A, so this clearly isn't your real code (as otherwise B can't override it) but when you make that change, it will return 3. If it didn't, polymorphism would be completely broken.
Now, the other change we could make to the code you've posted is in B. If you use:
public new int SomeMethod()
{
return 3;
}
Then your assertion would fail - because it would be calling A.SomeMethod() which is shadowed or hidden by B.SomeMethod(), not overridden. Basically, if you want polymorphic behaviour, you need to use override, and it has to be on a virtual method.
I suggest reading up on the topic here
In the article it shows these code examples:
class A
{
public void F() { Console.WriteLine("A.F"); }
public virtual void G() { Console.WriteLine("A.G"); }
}
class B: A
{
new public void F() { Console.WriteLine("B.F"); }
public override void G() { Console.WriteLine("B.G"); }
}
class Test
{
static void Main() {
B b = new B();
A a = b;
a.F(); //prints A.F
b.F(); //prints B.F
a.G(); //prints B.G (due to virtual method override)
b.G(); //prints B.G
}
}
Given your edit stating that you cannot redefine class A, I'm afraid you're more or less out of luck.
It's possible to derive B from A, and then declare new int SomeMethod(), but you won't be able to call that method with an A reference. You could use a run-time type check:
int CallSomeMethod(A obj)
{
var b = obj as B;
return b == null ? obj.SomeMethod() : b.SomeMethod();
}

Categories