我有基类(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
,但在实践中,它实际上隐藏了我的方法。
可能有人可能会澄清这一点,如果基类中的方法不允许被覆盖但是真的需要覆盖它,那么声明具有相同名称的方法是一种好习惯吗?
答案 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