C# Sealed 防止一个方法被派生

C# Sealed Prevent a method to be derived

我试图阻止我的 Base Class 派生出它的一种方法,但似乎不可能按照我喜欢的方式去做,我想我做错了。

你能帮忙吗? :) 我真的很想成功使用密封关键字!

这里有一些代码:

public class BaseClass
{
    public void MyMethod1(string input)
    {
        // Doing stuff here
    }
    public sealed void MyMethod2(string input)
    {
        // Doing stuff here
    }
}
public class DerivedClass : BaseClass
{
    // Other fields and stuff over there
}

发生的事情是有问题的,关键字 sealed 不允许在第一级派生的方法上使用。 我只有一个派生级别,我正在寻找的是避免在 DerivedClass.

中派生 MyMethod2

但好像不太对:/ 有什么建议或更正吗?

提前致谢:)

编辑:经过多次评论和午餐暂停后,我将尝试明确我的问题!

我真正想做的是防止我的 class 使用 "she" 继承的方法之一。 你们中有些人提到使用组合而不是继承,因为我似乎误解了它的意思。

我认为组合只存在于 UML 中而不存在于代码中。 C# 代码中的作曲听起来像什么?

如果这是第一层,派生的 class 无法覆盖它,除非标记为 virtualabstract

public class BaseClass
{
    public virtual void MyMethod1(string input)
    {
        // Doing stuff here
    }
    public void MyMethod2(string input)
    {
        // Doing stuff here
    }
}
public class DerivedClass : BaseClass
{
    public override void MyMethod1(string input){..}

    /// MyMethod2 is not overridable
}

根据您在下面的评论,您真正想要的似乎是组合,而不是继承;也就是说 DerivedClass 应该能够访问 BaseClass 上的某些功能,但不能以任何方式更改它。对于您的 class 示例,这可能类似于下面的内容。

public class CompositeFunctionality
{
    public void MyMethod1(string input)
    {
        // Doing stuff here
    }
}
public class BaseClass
{
    private CompositeFunctionality composite = new CompositeFunctionality();
    public void MyMethod2(string input)
    {
        // this is accessible in the base class
        composite.MyMethod1();
    }
}

public class DerivedClass : BaseClass
{
    public void MyMethod3(string input)
    {
         // do whatever you want
         // but composite is not accessible here
    }
}

您需要另一个继承级别才能使用 sealed。您可以在基础 class 中标记方法 virtual,在第二个 class.

中标记方法 override sealed

您可以将 "absolute base" 抽象化,因此无法实例化它,然后继承它来实现和密封它:

public abstract class VeryBaseClass
{
    public abstract void MyMethod2(string input);
}

public class BaseClass : VeryBaseClass
{
    public override sealed void MyMethod2(string input)
    {

    }
}

public class DerivedClass : BaseClass
{
    // Other fields and stuff over there
}

但是像 一样,方法在 C# 中默认是密封的。

相反,要能够重写一个方法,无论如何都必须将其标记为 virtual,因此您的问题似乎根本不是问题。只需将 MyMethod1 标记为 virtual 这样您就可以 可以 覆盖它,并且 MyMethod2 将保持非虚拟,因此根本无法覆盖。

sealed 关键字隐含在基础 class 中的任何方法中,该方法还不是虚拟的或抽象的(因此可覆盖)。

查看此link on MSDN了解更多信息

您只能密封覆盖基class 中虚方法的method/property。您的 MyMethod2 不是虚拟的,因此无法密封。事实上,它不是虚拟的,因此隐含地密封了它!

这样试试..

class Base 
{
 public virtual void Test() { ... }
}

class Subclass1 : Base 
{
 public sealed override void Test() { ... }
}

class Subclass2 : Subclass1 
{
 public override void Test() { ... } // FAILS!
// If `Subclass1.Test` was not sealed, it would've compiled correctly.
}

我正在重命名方法以便更好地理解。

public class BaseClass
{
    public void MethodToBeInherited(string input)
    {
        // Doing stuff here
    }
    public void MethodNotToBeInherited(string input)
    {
        // Doing stuff here
    }
}
public class DerivedClass : BaseClass
{
    // Other fields and stuff over there
    //MethodoBeInherited should be available
    //MethodNotToBeInherited should not be available
}

你想要的条件使用这种层级是不可能的(是一种关系),因为DervicedClass是一个BaseClass。因此,根据继承规则,您一定可以访问所有 BaseClass public 方法。

但是有一个替代方法可以解决这个问题——有关系。 继承和实现你想要的是不可能的,因为你会打破继承规则。所以让派生class由基数class组成就可以实现了。

interface I
{
    void MethodToBeInherited(string input)
}

class BaseClass
{
    public void MethodToBeInherited(string input)
    {
        // Doing stuff here
    }
    public void MethodNotToBeInherited(string input)
    {
        // Doing stuff here
    }
}

class DerivedClass : I
{
    public void MethodToBeInherited(string input)
    {
        b.MethodToBeInherited(input);
    }

    private BaseClass b;
}