覆盖/隐藏明确实现的接口方法

时间:2012-12-18 05:41:11

标签: c# inheritance interface explicit-implementation

我无法覆盖显式实现接口的方法。

我有两节课。一个名为OurViewModel的基础名称和一个名为MyViewModel的继承名称。他们共享一个名为Validate的方法,直到最近我才能隐藏方法的基本版本,如下所示:

public class OurViewModel
{
  public bool Validate(ModelStateDictionary modelState){ return true; }
}


public class MyViewModel : OurViewModel
{
  public new bool Validate(ModelStateDictionary modelState) {return false;}
}

这一切都在几天前发生了变化。现场出现了一个新界面 -

public interface IValidatableObject
{
  IEnumerable<ValidationResult> Validate(ValidationContext validationContext);
}

随后,OurViewModel也被更改了。我没有要求这个,但它发生了,我必须忍受它。该课程现在看起来像这样:

public class OurViewModel : IValidatableObject
{
  IEnumerable<ValidationResult> IValidatableObject.Validate(ValidationContext validationContext) {..}
}

我很难弄清楚如何在MyViewModel中覆盖或隐藏这个重写的Validate方法。如果我尝试将new关键字放在方法签名上(就像我原来的那样),我会收到编译错误。我也无法在OurViewModel中将Validate方法声明为虚拟,因为它明确地实现了一个接口。

怎么办?如果我只是使用IValidatableObject中的签名在MyViewModel中重新实现Validate,那么是否会隐藏OurViewModel中的实现,还是因为继承规则而在某种程度上要求麻烦?

2 个答案:

答案 0 :(得分:4)

我认为你需要在派生类中隐式实现这个接口。

public class MyViewModel : OurViewModel, IValidatableObject
{
    IEnumerable<ValidationResult> IValidatableObject.Validate(ValidationContext validationContext)
    {
        //...
    }
}

然后

OurViewModel v = new OurViewModel();
MyViewModel m = new MyViewModel();

IValidatableObject ivo = v;
ivo.Validate(null);

ivo = m;
ivo.Validate(null);

此外,如果接口是显式实现的,则只能通过对接口的引用来访问实现。请记住,如果您尝试

OurViewModel v = new OurViewModel();
v.Validate(null);

它将调用类的原始Validate方法,而不是接口实现。我认为应该删除旧的方法以避免可能的错误。

答案 1 :(得分:0)

您真的需要在Base类中显式实现IValidatableObject吗?

  

解决方案是 - 隐式实现IValidatableObject   基类,将其标记为虚拟。

: -

  

然后在派生类中实现IValidatableObject,隐含地和   将其标记为虚拟新。别忘了在派生时使用接口名称   课程定义。

这与@Konstantin Vasilcov的回答完全不同。 使用这种方法,您可以拥有更多可以覆盖行为的MyViewModel派生类。