我有实现IClientValidatable的基类

时间:2011-08-18 02:51:10

标签: c#

我有基类(CompareAttribute),它实现了IClientValidatable

[AttributeUsage(AttributeTargets.Property)]
public class NotContainsAttribute : CompareAttribute
{
}

我想覆盖方法IEnumerable<ModelClientValidationRule> GetClientValidationRules

但我不能这样做,因为它不是虚拟的(cannot override inherited member, because it is not marked virtual, abstract, or override)。

所以我只是在我的NotContainsAttribute

中声明我自己的方法
public new IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
}

我运行程序后所有工作都按预期工作但我在编译时得到警告,我的班级隐藏了继承的成员,(Warning "NotContainsAttribute" hides inherited member Use the new keyword if hiding was intended.

但如果我使用new关键字

public new IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
        {
            yield return new ModelClientValidationNotContains (this.FormatErrorMessage(metadata.GetDisplayName()), CompareAttribute.FormatPropertyForClientValidation(this.OtherProperty));            
            yield break;
        }

在这种情况下我的方法没有使用,而是使用基类方法。

我想要使用我的方法,没有new关键字我会使用它,但为什么编译器说我需要使用new关键字if hiding was intended

我理解if hiding was intended表示if you want to hide base method and use your method insteard mark it with new keyword,但在实践中,它实际上隐藏了我的方法。

可能有人可能会澄清这一点,如果基类中的方法不允许被覆盖但是真的需要覆盖它,那么声明具有相同名称的方法是一种好习惯吗?

3 个答案:

答案 0 :(得分:1)

它只是一个警告,当在调用方法中使用调用此方法时,您可能会意外地调用此隐藏方法,而您的意图不是这样。通过为它提供新的范围,你给出一个新的定义而不是掩盖它。

警告并不意味着您的代码不完整或错误,它只是让您不必监督您的错误并在将来敲门。

答案 1 :(得分:1)

我不认为您对情况的评估是正确的:如果基类方法未标记为虚拟,则默认情况下您的方法实现将隐藏它。

来自MSDN

  

如果派生类中的方法前面没有new或override   关键字,编译器将发出警告,该方法将表现出来   好像新关键字已经存在。

你只是得到编译器警告,因为通常这不是程序员的意图,它让你有机会纠正这个常见的错误 - 通常你想覆盖基类实现。不管你是否用new标记你的方法都没有区别 - 这只是让它显式你实际上隐藏了基类方法。

另请注意,隐藏基类方法将不允许以多态方式使用此方法:作为指向派生类实例的基类类型的对象引用将使用基类方法:

CompareAttribute foo = new NotContainsAttribute();
foo.GetClientValidationRules(..) // will call base class method

因此,只有在类型为NotContainsAttribute的对象引用上调用方法时,才会调用您的方法:

NotContainsAttribute bar = new NotContainsAttribute();
bar.GetClientValidationRules(..) // will call your method

另请参阅"Versioning with the Override and New Keywords (C# Programming Guide)""Polymorphism, Method Hiding and Overriding in C#"作为参考。

答案 2 :(得分:1)

如果方法未标记为虚拟,则无法更改该方法的功能。使用 new 关键字很少会对您有所帮助,因为任何引用基类而不是您的类的代码仍将使用基类的实现。

以下是对覆盖之间区别的解释:Difference between new and override