无法封闭,因为它不是一个覆盖。

13
我有以下类:

I've the following class:

namespace Warnings
{
    public abstract class BaseWarningIntField : IWarningInnerDataField
    {
        public string PropName;

        public string HeaderCaption;

        public sealed WarningInnerDataType DataType
        {
            get { return WarningInnerDataType.Integer; }
        }
    }
}

我希望最后一个属性 DataType 不可重载,因为它是整数类型的警告详细字段的基类,所以它需要始终返回正确的类型WarningInnerDataType.Integer

无论如何,编译器给了我以下错误提示:

  

'Warnings.BaseWarningIntField.DataType' 无法被密封,因为它不是重写

但就我所知,override 正好与我尝试实现的相反。


3
你为什么不在你的实现中尝试重写这个方法呢?进行一次快速实验后,你可能会重新思考这个问题。 - Austin Salonen
10
那就别虚拟化它,不需要封存。 - Brandon Moretz
1
交替使用静态只读。 - Dhawalk
@0A0D和相应的方法。请参考C#语言规范的第10.6.5节。 - Brian Rasmussen
1个回答

22

C# 中,默认情况下所有方法都是非虚拟的。您无法在子类中覆盖非虚拟方法。因此,将属性保留为通常状态将使您免受子类覆盖。

Sealed 是用于类声明的关键字,用于继承限制或用于停止类层次结构成员的虚拟链。但同样适用于虚拟方法和属性。

试图在子类中覆盖“普通”属性将导致编译错误

  

'WarningIntField.DataType.get':无法覆盖继承的   成员'BaseWarningIntField.DataType.get',因为它不是   标记为virtual、abstract或override

为了回答您的评论,我将提供一些代码示例来说明我的观点。实际上,您无法限制派生类隐藏方法或属性。因此,下一个情况是合法的,并且没有办法克服它(这也涉及虚拟方法和带有new关键字的方法)。

class BaseClass
{
    public string Property {get; set;}
}

class DerivedClass : BaseClass
{
    //compiler will give you a hint here, that you are hiding a base class prop
    public string Property {get; set;}
}

你无法通过局部变量限制或隐藏类中的字段,同样的道理也适用于这种情况。请注意,编译器还会帮助你注意到,你正在通过局部变量隐藏类字段。这也与 readonlyconst 和简单的 static 字段有关。

int field = 0; //class field
void Foo()
{
    int field = 0; //local variable
}

4
MSDN 中得知:你可以在重写基类的虚拟方法或属性时,在方法或属性上使用 sealed 修饰符。这样做可以让其他类从你的类派生,同时防止它们重写特定的虚拟方法或属性。 - Austin Salonen
@AustinSalonen 感谢您的提醒。我忘记了您可以通过密封来停止虚拟链。但是,这仅适用于虚拟方法。 - Ilya Ivanov
好的,我明白了。但是有没有一种方法可以阻止其他人隐藏我的方法?目前任何人都可以通过编写一个同名方法来实现这一点。 - Teejay
@Teejay 我已经在回答中添加了一些解释和代码。 - Ilya Ivanov
1
有趣。因此,“sealed”特别指“防止这个已经虚拟的方法被进一步覆盖”,而不仅仅是“防止这个方法被覆盖”。 - Stewart

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接