【问题标题】:Overriding / hiding an explicity implemented interface method覆盖/隐藏显式实现的接口方法
【发布时间】:2012-12-18 05:41:11
【问题描述】:

我在重写显式实现接口的方法时遇到问题。

我有两节课。一个名为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 中的实现,还是因为继承规则而以某种方式自找麻烦?

【问题讨论】:

  • 你在这个问题上又犯了一个错误。如果基成员不是虚拟的,你不能在派生类中使它成为新的。
  • @Dhananjay 你错了...
  • @KonstantinVasilcov ,所以你的意思是如果基本成员不是虚拟的,你仍然可以让它成为新的?
  • @Dhananjay 绝对。阅读new Modifier (C# Reference)

标签: c# inheritance interface explicit-implementation


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

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

    :-

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

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

    【讨论】:

      猜你喜欢
      • 2016-09-15
      • 2012-12-04
      • 1970-01-01
      • 1970-01-01
      • 2022-01-01
      • 2012-09-01
      • 2015-10-17
      • 2013-01-16
      • 2011-08-04
      相关资源
      最近更新 更多