假设您可以访问实现“IFoo”的基类“MyClass”。 'IFoo'定义函数'int FooValue()','MyClass'显式实现它。现在假设您有一个名为'MySubClass'的'MyClass'的子类,并且您希望覆盖该子类中的'FooValue',但您还希望子类的实现基于基类实现的结果。
现在通常,这可以通过简单地将实现移动到基类中的受保护函数来解决,我们在子类中将其简单地覆盖。做完了。但是我们无法访问基类的源代码。我们只将其作为库的参考。那你怎么解决这个问题呢?
这里有这个问题...... C#: Property overriding by specifying the interface explicitly ...当你无法通过正常渠道本身覆盖基类的界面时,你可以显式重新在子类上实现相同的接口,其行为类似于覆盖接口(但实际上你正在重新实现它,而不是覆盖它。)那就是说,我想弄清楚的是我如何获得在基类的实现。 (这就是为什么恕我直言,这不是那个问题的重复。)
这是基类的一些伪代码,我们再也无法访问代码......
public interface IFoo
{
int FooValue();
}
public class MyClass : IFoo
{
int IFoo.FooValue() <-- Explicit implementation requiring a cast to access.
{
return 4;
}
}
这是我们要做的,但显然不允许这样做,因为你不能像这样使用'base'。
public class MySubClass : MyClass
{
int IFoo.FooValue()
{
int baseResult = ((IFoo)base).FooValue(); <-- Can't use 'base' like this
return baseResult * 2;
}
}
这可能吗?
答案 0 :(得分:3)
我会诚实地说,没有直截了当的答案。感觉像是语言的限制。可能有一些合理的原因缺乏它。
但是,我可以想到一些不那么干净的工作。
反思。 Imho,这里最简单的选择。真正需要反思的极少数情况之一。
您自己的接口和基类派生自引用的库。
//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;
}
}
您处理的是IRealFoo
,MyRealClass
,而不是IFoo
,MyClass
等。
IRealFoo x = new MyRealClass();
IRealFoo y = new MyRealSubClass();
Console.WriteLine(x.FooValue()); //4
Console.WriteLine(y.FooValue()); //8
与上述相同,但抽象类而非接口。
与上面相同,但您也可以使用抽象基类RealFoo
而不是接口IFoo
。我认为这是一个稍微简单的代码,但不一定是好的代码。它彻底改变了代码的意图。
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
扩展方法以及动态。
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();
}
在这种情况下,您可以使用熟悉的IFoo
界面,但您必须调用扩展方法RealFooValue
而不是FooValue
。调用FooValue
时,这可能会导致错误的结果。我不建议。
IFoo x = new MyRealClass();
IFoo y = new MyRealSubClass();
Console.WriteLine(x.RealFooValue()); //4
Console.WriteLine(y.RealFooValue()); //8
使用if-else
逻辑启用类型。
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();
}
这与上述问题相同。不推荐它。
IFoo x = new MyClass();
IFoo y = new MySubClass();
Console.WriteLine(x.RealFooValue()); //4
Console.WriteLine(y.RealFooValue()); //8
答案 1 :(得分:0)
显式接口实现意味着IFoo.FooValue()是私有 (你可以通过反思来检查):
MethodInfo mi = typeof(MyClass).GetMethods(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance).Where(m => m.Name.EndsWith("IFoo.FooValue")).ToList()[0];
if (mi.IsPrivate) {
// And it is private....
}
所以你不能打电话给 继承了IFoo.FooValue()。
可能的道路
public interface IFoo
{
int FooValue();
}
public class MyClass : IFoo
{
// This (main logic) should be inherited/override
protected virtual int CoreFooValue()
{
return 4;
}
// Just a non-virtual interface method which is immutable
int IFoo.FooValue()
{
return CoreFooValue();
}
}
public class MySubClass : MyClass {
// Logic is changed, interface is not
protected override int CoreFooValue()
{
return base.CoreFooValue() * 2;
}
}
另请参阅非虚拟接口模式