C#阻止基类方法被派生类中的new修饰符隐藏

时间:2013-08-07 20:22:53

标签: c# inheritance

这是我的情况。在Java中,我可以在base / super类中将方法标记为final,并且派生类无法屏蔽相同签名的方法。但是在C#中,new关键字允许继承我的类的人创建具有相同签名的方法。

请参阅下面的示例。我需要保持orignal.MyClass公开,所以请不要建议作为答案。这似乎是一个从Java转移到C#

的迷失功能
public class orignal.MyClass{
    public void MyMethod()
    {
     // Do something
    }
}

class fake.MyClass: orignal.MyClass {
    // How to prevent the following
    public new void MyMethod()
    {
     // Do something different
    }
}

编辑:不重复。

所有答案似乎都暗示,不可能阻止方法在派生类中隐藏/隐藏。在将一些旧的Java代码迁移到C#时,这一点变得很明显。 Java中的最终方法不允许任何人在任何派生类中使用相同的方法签名。虽然在大多数场景中C#允许在派生类中使用相同签名的方法,但如果有必要,可以防止这种行为。

4 个答案:

答案 0 :(得分:10)

  

//如何防止以下

没有办法阻止这种情况。这是语言所允许的。

请注意,在实践中,这很少重要。如果您希望将基类用作作为类,则仍将调用您的方法。使用new时,只有在声明为DerivedClass的变量中使用DerivedClass时才会隐藏该方法。

这意味着,如果将实例传递到您的方法中,您的API(如果围绕MyClass构建)将始终仍然会调用MyMethod


编辑以回应评论:

如果你担心人们会对你的课程进行一般性的分类,你唯一真正的选择就是密封你的课程:

public sealed class MyClass
{

这将阻止人们完全创建子类。但是,如果您希望允许人们从您的班级派生,则无法阻止他们将您的方法隐藏在班级中。

答案 1 :(得分:3)

您无法阻止公开方法或财产被屏蔽,但为什么会这样?从扩展基类的人那里采取故意行动(即他们需要输入new),所以他们打算这样做,为什么要试着阻止他们呢?

也许您需要将模式切换一下?如果扩展器必须使用你的基本方法,那么你可以在其中加入一些关键的东西,从而迫使他们调用它。当然,如果没有正确完成,这很臭,所以如果你使用这种方法,那么将你的方法标记为virtual,然后在文档(或方法标题注释)中提到必须调用基本方法。这样你就可以避免扩展器隐藏/掩盖你的方法(尽管它们仍然可以),但是如果他们想要它们仍然可以扩展它。

答案 2 :(得分:0)

我假设你真的想阻止某人覆盖该方法 - 隐藏一个new的方法无法阻止,但它不会给基类带来任何风险,所以不应该是一个问题。

在C#中,默认情况下不能覆盖方法。因此,您可以通过不将其标记为virtualabstract来阻止某个表单覆盖基本方法。在Java中,默认情况下方法是虚拟的,因此使用final密封方法是必要的,以防止覆盖。

答案 3 :(得分:0)

我认为唯一的方法是创建接口,将你的方法定义放在其中,然后让原始类实现接口并明确地实现该方法:

    interface IAnimal
    {
        string diary(string notes, int sleephours);   
    }

    class Dogs:IAnimal
    {        

virtual public string voice()
        {
            string v = "Hao Hao"; return v;
        } 
        string IAnimal.diary(string notes,int sleephours)
        {
            return notes + sleep.ToString() + " hours";
        }

    }

    class Cats:Dogs
    {
        public override string voice()
        {
            string v = "Miao Miao"; return v;
        }
    }

您不会通过Cats实例使用diary()方法。