2

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

我有两节课。一个基础的称为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关键字放置在方法签名中(就像我最初所做的那样),我会收到编译错误。我也不能Validate在 OurViewModel 中将该方法声明为虚拟方法,因为它显式地实现了一个接口。

该怎么办?如果我只是使用来自 IValidatableObject 的签名在 MyViewModel 中重新实现Validate,那会隐藏 OurViewModel 中的实现,还是因为继承规则而以某种方式自找麻烦?

4

2 回答 2

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类的原始方法,而不是接口实现。我认为应该删除旧方法以避免可能的错误。

于 2012-12-18T05:51:26.970 回答
0

你真的需要在基类中显式地实现 IValidatableObject 吗?

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

:-

然后在派生类中隐式实现 IValidatableObject,并将其标记为虚拟新。不要忘记在派生类定义上使用接口名称。

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

于 2012-12-18T16:52:27.450 回答