【问题标题】:How to have a sealed constructor?如何拥有一个密封的构造函数?
【发布时间】:2011-11-28 02:45:42
【问题描述】:

我有一个具有公共构造函数的基类。

基类不是密封的,也不是抽象的。

有一个我希望被密封的构造函数。这可能吗?

我当前的尝试导致语法错误,说构造函数不能被密封。

public sealed MyBase(string someParam)

补充:

我希望能够直接实例化基类并访问密封的构造函数。派生类不能通过派生构造函数使用该构造函数。 例如。

public MyDerived() : base(string cant_access_my_sealed_constructor)

【问题讨论】:

  • 什么意思?构造函数不是继承的,也不是虚拟的。其中一个怎么可能是sealed
  • 我只说The baseclass is not sealed and is not abstract.
  • 对否决票有何评论?

标签: c# constructor sealed


【解决方案1】:

你不能那样做。如果构造函数是public,则可以从派生类的构造函数中调用。但是你可以做一些接近的事情——你可以有一个 private 构造函数和一个调用它的 public static 方法:

class MyBase
{
    private MyBase(string someParam)
    {
        // some code
    }

    public static MyBase Create(string someParam)
    {
        return new MyBase(someParam);
    }

    protected MyBase() // or some other protected or public constructor
    { }
}

class MyDerived : MyBase
{
    public MyDerived()
        : base("foo") // won't compile, as requested
    { }
}

【讨论】:

  • 如果您没有任何子类可以访问的构造函数,您不妨将您的类设为sealed
  • 这是一个非常好的答案,也是我一直在寻找的解决方法。谢谢!
  • @StriplingWarrior,是的,但从我认为派生类中至少有一个其他构造函数可用的问题。我已经在我的回答中澄清了代码。
  • 啊,这更有意义。 +1
【解决方案2】:

所有构造函数都是“密封的”,因为它们不能被“覆盖”。它们只能从子类的构造函数中调用。

如果您希望阻止子类具有具有相同签名的构造函数,则无法做到。

根据您添加到帖子中的其他信息,听起来您想要做的就是将您的构造函数设为私有,正如 Kyle 建议的那样。这将阻止子类调用构造函数,但不会阻止它采用相同类型的参数:

public class Foo
{
    private Foo(string s){
    }
    // Allowed
    public Foo() : this("hello") {
    }
}

public class Bar : Foo
{
    // Allowed
    public Bar(string s) : base(){
    }
    // Not allowed
    public Bar(string s) : base(s){
    }
}

【讨论】:

  • @Valamas:我根据您更新的问题添加了更多信息。
【解决方案3】:

如果要防止构造函数被继承的类调用,只需将其标记为私有即可。

子类不继承构造函数,如果需要,您必须显式调用基构造函数。

当子类的实例被实例化时,此代码将调用基类的无参数构造函数。没有它,在创建子类的新实例时将不会调用基类的构造函数。

public class A
{
    public A() 
    {
    }
}

public class B : A
{
    public B() 
        : base() 
    {
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-02-27
    • 2021-07-20
    • 1970-01-01
    • 1970-01-01
    • 2010-09-12
    • 2013-08-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多