I also had a situation where I thought I wanted to override an explicit interface implementation and call the base class and found this question with its answers saying "can't be done".
The first thing to note is that in order to override the explicit interface implementation WITHOUT calling the base class is fairly simple. The derived class merely needs to implement the interface itself.
public class ChildTest : ParentTest, ITest
{
string ITest.Speak()
{
return "Mooo";
}
// Note: any other interface functions will call ParentTest's implementation
}
However, there is now no "legitimate" way to call ParentTest
's implementation of ITest.Speak
on an object of type ChildTest
, as any attempt to use the interface will result in ChildTest
's implementation being called instead.
Thus, it is only the call to the base implementation that causes complication. To satisfy my curiosity, I proved that it CAN be done, but really it shouldn't...
Leaving the base class unchanged, the following does in fact allow the base class to be called using reflection.
public class ChildTest : ParentTest, ITest
{
string ITest.Speak()
{
return "Mooo" + typeof(ParentTest).GetMethod("ITest.Speak", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(this, new object[0]) as string;
}
}
NB if the sample code is enclosed in a namespace, the fully qualified interface name is required. e.g. "MyNamespace.ITest.Speak"
If the function will be called repeatedly and/or for many objects, performance can be improved by caching the method info, and/or creating a delegate for the base call, e.g.:
public class ChildTest : ParentTest, ITest
{
static ChildTest()
{
baseSpeakMethodInfo = typeof(ParentTest).GetMethod("ITest.Speak", BindingFlags.Instance | BindingFlags.NonPublic);
}
static private MethodInfo baseSpeakMethodInfo;
public ChildTest()
{
baseSpeak = baseSpeakMethodInfo.CreateDelegate(typeof(Func<string>), this) as Func<string>;
}
private Func<string> baseSpeak;
string ITest.Speak()
{
return "Mooo" + baseSpeak();
}
}
The only advantage this has over other answers is that it works if you cannot modify the base class. Otherwise, it's a horrible solution, and a mechanism should be created in the base class (as in other answers) to provide the derived class with a legitimate way to call the base implementation.