Bit of a dumb question, but I'm wondering what the accepted way of passing data from back to an overridden base method is in c#.
e.g. I guess I could do:
class A
{
int x;
public virtual void DoStuff() {
Console.WriteLine(x);
}
}
class B : A
{
public override void DoStuff() {
x = 1;
base.DoStuff();
}
}
But is there a better method that for example doesn't require the use of a member variable?
One solution can involve the use of a protected method that has an argument to reuse code from the base class.
class A
{
public virtual void DoStuff() {
DoStuffInternal(0);
}
protected void DoStuffInternal(int x) {
Console.WriteLine(x);
}
}
class B : A
{
public override void DoStuff() {
DoStuffInternal(1);
}
}
Why not use a parameter?
class A
{
public virtual void DoStuff(int x) {
Console.WriteLine(x);
}
}
class B : A
{
public override void DoStuff(int x) {
//do stuff
int y = 1
base.DoStuff(y);
}
}
How about
abstract class A
{
protected abstract int X { get; }
public void DoStuff() {
Console.WriteLine(X);
}
}
class B : A
{
protected override int X { get { return 1; } }
}
You may use something like Template Method design pattern:
class A
{
public void DoStuff() {
var x = DoGetX();
Console.WriteLine(x);
}
protected abstract int DoGetX();
}
class B : A
{
protected override int DoGetX() {
return 1;
}
}
For almost every developer property is looks like simple wrapper around field, and we know that there are no such thing like virtual fields. So I think that abstract method is much more preferable solution in this case(we already discussed differences between properties and methods here).
Related
Here is an example of what I am looking to do.
public class ParentA {}
public class ChildA : ParentA
{
public string x;
}
public class A
{
public virtual void DoSomething(Parent a)
{
// perform something
}
}
public class B : A
{
public Override void DoSomething(Child a)
{
// perform something slightly different using both strings
a.x = "something";
}
}
but turn out I got an error with "No Suitable Method found to Override".
So I want to override DoSomething from class A and pass a different set of child class parameter. Is this possible?
When you override something, the signature of the method has to be the same.
So in your case, you can do something like this
public class Parent { }
public class Child : Parent
{
public string x;
}
public class A
{
public virtual void DoSomething(Parent a)
{
// perform something
}
}
public class B : A
{
public override void DoSomething(Parent a)
{
if (a is Child child)
{
// perform something slightly different using both strings
child.x = "something";
}
}
}
I'm not 100% sure exactly what you're trying to accomplish, however generics may help you:
public class Parent { }
public class Child : Parent
{
public string x;
}
public class A<T> : Parent where T : Parent
{
public virtual void DoSomething(T a)
{
}
}
public class B : A<Child> // Child could also be Parent here
{
public override void DoSomething(Child a)
{
a.x = "test";
}
}
Basic problem (pseudocode):
interface ISomethingDoer
{
void DoSomething();
}
class A: ISomethingDoer
{
void ISomethingDoer.DoSomething()
{
Something.Do();
}
}
class B: A, ISomethingDoer
{
void ISomethingDoer.DoSomething()
{
if (reason)
{
base.DoSomething(); //this does not compile
}
SomethingElse.Do();
}
}
Is there any way to make this work without removing the explicit implementation from class A?
I would suggest changing your base class a little such that DoSomething calls a protected method:
class A: ISomethingDoer
{
void ISomethingDoer.DoSomething()
{
DoSomethingImpl();
}
protected void DoSomethingImpl()
{
Something.Do();
}
}
And then in B you can call DoSomethingImpl:
class B: A, ISomethingDoer
{
void ISomethingDoer.DoSomething()
{
if (reason)
{
DoSomethingImpl(); //this does compile
}
SomethingElse.Do();
}
}
The alternative method suggested by Lasse V. Karlsen is to use reflection:
class B: A, ISomethingDoer
{
void ISomethingDoer.DoSomething()
{
if (reason)
{
string baseName = $"{typeof(ISomethingDoer).FullName}.{nameof(DoSomething)}";
MethodInfo baseMethod = this.GetType().BaseType
.GetMethods(BindingFlags.NonPublic | BindingFlags.Instance)
.FirstOrDefault(m => m.IsPrivate && m.IsFinal && m.Name == baseName);
baseMethod.Invoke(this, new object[0]);
}
SomethingElse.Do();
}
}
But I don't like this approach since it uses reflection and is going to be slower. I used this answer to help me build the reflection solution.
You can use GetParameters() if you need to filter different overloads of the method, and you can specify arguments by building an object[] array containing them in the same positional order.
You aren't able to call base on an interface type, but you could refactor your classes to make this possible.
By moving the content of your method into a protected method, you can call it directly by both classes, like this:
interface ISomethingDoer
{
void DoSomething();
}
class A : ISomethingDoer
{
void ISomethingDoer.DoSomething()
{
_DoSomething();
}
protected void _DoSomething()
{
Something.Do();
}
}
class B : A, ISomethingDoer
{
void ISomethingDoer.DoSomething()
{
if (reason)
{
base._DoSomething();
}
SomethingElse.Do();
}
}
This might be a good basic implementation:
public interface IAnimal
{
void Eat();
}
public class Animal : IAnimal
{
public void Eat()
{
Console.WriteLine("This Animal is Eating!");
}
}
public class Shark : Animal
{
public void Eat(bool useBase)
{
if (useBase)
{
base.Eat();
}
else
{
Console.WriteLine("This Shark is devouring everything with 120840128904 teeth");
}
}
}
I always make private implementation as wrappers to methods.
interface ISomethingDoer
{
void DoSomething();
}
class A : ISomethingDoer
{
protected void DoSomething()
{
Something.Do();
}
void ISomethingDoer.DoSomething() => DoSomething();
}
class B : A, ISomethingDoer
{
protected void DoSomethingElse()
{
if (reason)
{
base.DoSomething();
}
SomethingElse.Do();
}
void ISomethingDoer.DoSomething() => DoSomethingElse();
}
I have implemented a method in the base class as following:
class A
{
protected void f1()
{
}
}
class A1 : A
{
public void f2()
{
//Simple Calling
f1();
//Calling using base pointer
base.f1();
}
}
What is the difference between the calling simply and calling using a base pointer ? What are the advantages of either of the ways?
In your example there is no difference. However, consider situation when f1 is virtual and it has another implementation in A1 class:
class A
{
protected virtual void f1()
{
Console.WriteLine("A");
}
}
class A1 : A
{
public void f2()
{
//Simple Calling - prints `A1`
f1();
//Calling using base pointer - prints `A`
base.f1();
}
protected override void f1()
{
Console.WriteLine("A1");
}
}
f1() is different than base.f1() then. The same situation appears when you use new keyword to hide base implementation within derived class:
protected new void f1()
{
Console.WriteLine("A1");
}
The difference between this.f1() (or simply f1()) and base.f1() becomes relevant when you override a virtual method:
class A
{
public virtual void F()
{
Console.WriteLine("A");
}
}
class B : A
{
public override void F()
{
Console.WriteLine("B");
}
void Test()
{
F(); // Prints "B"
this.F(); // Prints "B"
base.F(); // Prints "A"
}
}
It's only useful if you have overloaded/shadowed a method defined in the base class.
class A1 : A
{
public void f2()
{
//Simple Calling
f1();
//Calling using base pointer
base.f1();
}
protected new void f1()
{
// I won't be called
}
}
Also useful when you want to extend the functionality of a base method, but don't want to replicate it:
class A
{
public virtual void F()
{
Console.WriteLine("A");
}
}
class B : A
{
public override void F()
{
base.F();
Console.WriteLine("B");
}
void Test()
{
F(); // Prints "A B"
}
}
In this case, none. But imagine this:
class A
{
public virtual void F()
{
}
}
class B : A
{
public override void F()
{
Console.WriteLine("B");
}
public void F2()
{
F(); /*output: B*/
base.F() /*no output*/
}
}
That's where base starts to come in useful.
The base keyword is used to refer to the base class when chaining constructors or when you want to access a member (method, property, anything) in the base class that has been overridden or hidden in the current class.
For example,
class A {
protected virtual void Foo() {
Console.WriteLine("I'm A");
}
}
class B : A {
protected override void Foo() {
Console.WriteLine("I'm B");
}
public void Bar() {
Foo();
base.Foo();
}
}
With these definitions,
new B().Bar();
would output
I'm B
I'm A
Reference
if you override f1, base its needed to differentiate between them.
class A
{
protected virtual void f1() { }
}
class A1 : A
{
protected override void f1() { }
public void f2()
{
//Simple Calling
f1(); <--- this will call to overrided f1 in this class
//Calling using base pointer
base.f1();
}
}
I need to call automatically base class method when calling overriden one (like constructors call base). For example:
class A
{
public void Fun()
{
Console.Write("Class A!");
}
}
class B : A
{
public void Fun()
{
Console.Write("Class B!");
}
}
I want to see on the screen
Class A! Class B!
when executing next code:
B b = new B();
b.Fun();
Could anyone tell me please what need to change in example code or how better to write to get required result? Thanks.
If you don't want to call it explicitly and therefore ensure A.Fun() is called in the derived class, you could use something called the template method pattern:
class A
{
public void Fun()
{
Console.Write("Class A!");
FunProtected();
}
protected virtual void FunProtected()
{
}
}
class B : A
{
protected override void FunProtected()
{
Console.Write("Class B!");
}
}
This would give you:
new A().Fun() -> "Class A!"
new B().Fun() -> "Class A! Class B!"
If you want such behavior you will need to change platform/language. .NET doesn't automatically call the base method. You need to call it explicitly. Also your method needs to be virtual or you will be hiding it in the derived class:
class A
{
public virtual void Fun()
{
Console.Write("Class A!");
}
}
class B : A
{
public override void Fun()
{
// call the base method which will print Class A!
base.Fun();
Console.Write("Class B!");
}
}
Now when you do this:
B b = new B();
b.Fun();
you will get the required result.
Can still be so:
interface IFun
{
void Fun();
}
abstract class A : IFun
{
void IFun.Fun()
{
Console.Write("Class A!");
Fun();
}
protected abstract void Fun();
}
class B : A
{
protected override void Fun()
{
Console.Write("Class B!");
}
}
IFun b = new B();
b.Fun();
This works if object reference is IFun.
Just for reference, you could use a wrapper pattern that puts an A inside a B. Here is a crude example!
interface IFunClass {
void Fun();
}
class A : IFunClass {
public void IFunClass.Fun() {
Console.Write("Class A!");
}
}
class B : IFunClass {
public B(IFunClass f) {
this.m_SomethingFun = f;
}
public void IFunClass.Fun() {
this.m_SomethingFun.Fun();
Console.Write("Class B!");
}
private IFunClass m_SomethingFun;
}
A a = new A();
B b = new B(a);
b.Fun() // will call a.Fun() first inside b.Fun()
I want to create a class that can only be inherited, for that i know it should be made abstract. But now the problem is that i want to use functions of that class without making them static. How can i do that.
public abstract Class A
{
A()
{}
public void display()
{}
}
public Class B:A
{
base.A() // this is accessible
this.display() // this is not accessible if i dont make this function static above
}
Your example will not compile, you could consider something like this:
using System;
public abstract class A
{
protected A()
{
Console.WriteLine("Constructor A() called");
}
public void Display()
{
Console.WriteLine("A.Display() called");
}
}
public class B:A
{
public void UseDisplay()
{
Display();
}
}
public class Program
{
static void Main()
{
B b = new B();
b.UseDisplay();
Console.ReadLine();
}
}
Output:
Constructor A() called
A.Display() called
Note: Creating a new B() implicitly calls A(); I had to make the constructor of A protected to prevent this error:
"'A.A()' is inaccessible due to its protection level"
That's not true. You don't have to make Display() static; you can call it freely from the subclass. On the other hand, you can't call the constructor like that.
Maybe it's just an error in the example, but the real issue with the code you have is that you can't put method calls in the middle of your class definition.
Try this:
public abstract class A
{
public void Display(){}
}
public class B:A
{
public void SomethingThatCallsDisplay()
{
Display();
}
}
Here's how you can do this..
public abstract class A
{
public virtual void display() { }
}
public class B : A
{
public override void display()
{
base.display();
}
public void someothermethod()
{
this.display();
}
}