Как получить герметичный конструктор? - PullRequest
1 голос
/ 30 сентября 2011

У меня есть базовый класс, который имеет публичные конструкторы.

Базовый класс не запечатан и не является абстрактным.

Есть один конструктор, который я хочу запечатать.Возможно ли это?

Моя текущая попытка приводит к синтаксической ошибке, говорящей, что конструктор не может быть закрыт.

public sealed MyBase(string someParam)

Дополнительно:

Я хочуиметь возможность напрямую создавать базовый класс и иметь доступ к запечатанному конструктору.Производные классы не могут использовать этот конструктор через производные конструкторы.Например,

public MyDerived() : base(string cant_access_my_sealed_constructor)

Ответы [ 3 ]

8 голосов
/ 30 сентября 2011

Вы не можете этого сделать. Если конструктор 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
    { }
}
6 голосов
/ 30 сентября 2011

Все конструкторы «запечатаны» в том смысле, что их нельзя «переопределить». Они могут быть вызваны только из конструктора дочернего класса.

Если вы хотите, чтобы у дочерних классов не было конструктора с такой же сигнатурой, это невозможно.

На основании дополнительной информации, которую вы добавили в пост, звучит так, как будто вы хотите сделать свой конструктор приватным, как предложил Кайл. Это предотвратит вызов дочерним классом конструктора, но не помешает ему принимать те же типы аргументов:

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){
    }
}
2 голосов
/ 30 сентября 2011

Если вы хотите предотвратить вызов конструктора унаследованными классами, просто отметьте его как закрытый.

Конструкторы не наследуются дочерним классом, при необходимости вы должны явно вызывать базовый конструктор.

Этот код будет вызывать конструктор без параметров базового класса, когда экземплярдочерний класс создается.Без этого конструктор базового класса не будет вызываться при создании нового экземпляра дочернего класса.

public class A
{
    public A() 
    {
    }
}

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