Say you have access to a base class 'MyClass' that implements 'IFoo'. 'IFoo' defines the function 'int FooValue()' and 'MyClass' implements it explicitly. Now say you have a subclass of 'MyClass' called 'MySubClass' and you want to override 'FooValue' in that subclass, but you also want the subclass's implementation to be based on the result from the base class's implementation.
Now normally, this would be solved by simply moving the implementation to a protected function in the base class which we'd then simply overide in the subclass. Done and done. But we don't have access to the source code of the base class. We only have it as a reference to a library. So how do you solve this?
There's this SO question here... C#: Property overriding by specifying the interface explicitly... that shows while you can't override a base class's interface through the normal channels per se, you can explicitly re-implement the same interface on a subclass and that behaves like you're overriding the interface (but in actuality you're re-implementing it, not overriding it.) That said, what I'm trying to figure out is how do I get at the base class's implementation. (That's why IMHO this isn't a duplicate of that question.)
Here's some pseudocode of the base class which again, we don't have access to code-wise...
public interface IFoo
{
int FooValue();
}
public class MyClass : IFoo
{
int IFoo.FooValue() <-- Explicit implementation requiring a cast to access.
{
return 4;
}
}
This is what we're trying to do, but obviously this isn't allowed because you can't use 'base' like this.
public class MySubClass : MyClass
{
int IFoo.FooValue()
{
int baseResult = ((IFoo)base).FooValue(); <-- Can't use 'base' like this
return baseResult * 2;
}
}
So is this possible?
I will be honest, there is no straightforward answer to this. Feels like a limitation of the language. May be there is some sound reason for the lack of it.
However, I can think of some not so clean work arounds.
Reflection. Imho, the simplest option here. One of those rare cases where reflection is really needed.
Your own interface and base class derived from referenced library.
//your interface
public interface IRealFoo : IFoo
{
new int FooValue();
}
//your base class
public class MyRealClass : MyClass, IRealFoo
{
protected virtual int FooValue()
{
return ((IFoo)this).FooValue();
}
int IRealFoo.FooValue()
{
return FooValue();
}
}
//your child class
public class MyRealSubClass : MyRealClass
{
protected override int FooValue()
{
return base.FooValue() * 2;
}
}
And you deal with IRealFoo
, MyRealClass
and so on instead of IFoo
, MyClass
etc.
IRealFoo x = new MyRealClass();
IRealFoo y = new MyRealSubClass();
Console.WriteLine(x.FooValue()); //4
Console.WriteLine(y.FooValue()); //8
Same as above but abstract class instead of interface.
Same as above, but you can also have an abstract base class RealFoo
instead of interface IFoo
. This I think is slightly easier code, but need not be good code. It completely changes the intent of the code.
public abstract class RealFoo : MyClass
{
public virtual int FooValue()
{
return ((IFoo)this).FooValue();
}
}
public class MyRealClass : RealFoo
{
public override int FooValue()
{
return base.FooValue();
}
}
public class MyRealSubClass : MyRealClass
{
public override int FooValue()
{
return base.FooValue() * 2;
}
}
//call it like:
RealFoo x = new MyRealClass();
RealFoo y = new MyRealSubClass();
Console.WriteLine(x.FooValue()); //4
Console.WriteLine(y.FooValue()); //8
Extension method along with dynamic.
public class MyRealClass : MyClass
{
public virtual int FooValue()
{
return ((IFoo)this).FooValue();
}
}
public class MyRealSubClass : MyRealClass
{
public override int FooValue()
{
return base.FooValue() * 2;
}
}
public static int RealFooValue(this IFoo foo)
{
return ((dynamic)foo).FooValue();
}
In this one case you can stick with familiar IFoo
interface, but you got to call the extension method RealFooValue
instead of FooValue
. This will be confusing with potentially wrong result when calling FooValue
. I dont advise it.
IFoo x = new MyRealClass();
IFoo y = new MyRealSubClass();
Console.WriteLine(x.RealFooValue()); //4
Console.WriteLine(y.RealFooValue()); //8
Switch on type with if-else
logic.
public class MySubClass : MyClass
{
}
public static int RealFooValue(this IFoo foo)
{
var type = foo.GetType();
if (type == typeof(MyClass))
return foo.FooValue();
else if (type == typeof(MySubClass))
return foo.FooValue() * 2; //logic goes here
throw new Exception();
}
This has the same problem as above. Dont recommend it.
IFoo x = new MyClass();
IFoo y = new MySubClass();
Console.WriteLine(x.RealFooValue()); //4
Console.WriteLine(y.RealFooValue()); //8
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With