从显式实现接口的基类重写方法

时间:2012-12-17 17:39:34

标签: c# inheritance interface

[编辑]

由于比原始帖子所需要的复杂程度稍高 - 我为此道歉 - 我会尝试简化一些事情。

最初,我的基类看起来像这样:

public class OurViewModel
{
  public bool Validate(ModelStateDictionary modelState){...}
}

我的类使用new关键字继承并隐藏了该方法:

public class MyViewModel : OurViewModel
{
  public new bool Validate(ModelStateDictionary modelState) {...}
}

同时,IValidatableObject接口出现了:

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

现在,OurViewModel(遗憾地)也被改变了。它看起来像这样:

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

我现在需要做的是再次隐藏MyViewModel中的Validate方法,但我无法弄清楚当前的安排是如何做到的。有没有好办法解决这个问题?

(FWIW,我同意在基类中添加新接口并不是完成任务的最佳方式,但这就是在这里发生的事情。)


[原帖]

我无法覆盖其中一个课程中的方法。有人改变了基类的继承模型:

public class OurViewModel : IntlViewModelBase<OurResources>

到此:

public class OurViewModel : IntlViewModelBase<OurResources>, IValidatableObject

IValidatableObject有一个方法签名Validate()

IEnumerable<ValidationResult> Validate(ValidationContext validationContext);

OurViewModel有一个看似如下的Validate方法:

public bool Validate(ModelStateDictionary modelState)

......现在是改变之后的事情:

IEnumerable<ValidationResult> IValidatableObject.Validate(ValidationContext validationContext)

与此同时,我的班级继承自OurViewModel。它使用new关键字来实现自己的布尔版Validate。

似乎我不再能够隐藏Validate方法,因为我的类没有实现IValidatableObject。现在对我来说覆盖那个方法的正确方法是什么?

4 个答案:

答案 0 :(得分:0)

我可能完全忽略了这一点,但这对我编译很好(使用了OurResourcesIntlViewModelBase<T>的存根类。)

public class OurViewModel : IntlViewModelBase<OurResources>, IValidatableObject
{
    public bool Validate(ModelStateDictionary modelState)
    {
        throw new NotImplementedException();
    }

    IEnumerable<ValidationResult> IValidatableObject.Validate(ValidationContext validationContext)
    {
        throw new NotImplementedException();
    }
}

public class MyViewModel : OurViewModel
{
    public new bool Validate(ModelStateDictionary modelState)
    {
        throw new NotImplementedException();
    }
}

答案 1 :(得分:0)

如果要覆盖新的Validate方法(IValidatableObject.Validate),只需添加虚拟关键字。

public virtual IEnumerable<ValidationResult> Validate(ValidationContext validationContext)

答案 2 :(得分:0)

我想我已经充分利用了这个问题,并决定再试一次这里提供的更简单的版本 - this one

感谢所有回复的人。管理员是否可以关闭此主题或将其指向/链接到新问题?我不确定这种情况下的SO礼仪是什么。

答案 3 :(得分:0)

少数事情:

1

  

如果你的基类中的每个方法都想要新的   在派生类中实现然后导出没有意义   从基地。继承的主要目的是代码重用。所以你可以简单地从父子中删除关系。

2

  

让我们假设在你的基类中有一些方法   实际上是继承。在那种情况下我不应该有一个   使用Virtual标记Base类的Interface成员的问题   关键字和派生类将其称为新的。

-

  

如果您正在询问实施此情况的不同方式   我们需要知道你的目标是什么。如果目标是派生成员   有了新的定义,那么更好的方法就是明确   在派生类中实现接口。

请提及您遇到的确切问题?是因为你无法使用新关键字,或者你正在寻求不同的方法来解决这种情况。