Подтвердить что ты не робот

Как я могу назвать оба инициализатора конструктора, base() и this()?

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

Я делаю самообследование моего кода, чтобы помочь "ожесточить" его для повторного использования, и я просто подошел:

public partial class TrackTyped : Component
{
    IContainer components = null;

    public TrackTyped()
        : base()
    {
        InitializeComponent();
    }

    public TrackTyped(IContainer container)
        : base()
    {
        container.Add(this);
        InitializeComponent();
    }
}

То, что я обычно делаю, когда вижу одну и ту же строку кода в двух конструкторах, это сделать один вызов другим с помощью "this()", но я не могу это сделать.

Если я правильно прочитал spec (я только начал читать спецификацию, чтобы я мог быть не прав):

10.11 Instance Constructors
   constructor-declarator:
      identifier   (   formal-parameter-listopt   )   constructor-initializeropt
   constructor-initializer:
      :   base   (   argument-listopt   )
      :   this   (   argument-listopt   )

Это говорит, что у меня может быть только один из них.

ВОПРОС: 10.11 подразумевает, что нет причин для вызова обоих или это просто означает, что язык поддерживает только вызов?

4b9b3361

Ответ 1

Нет необходимости вызывать оба, потому что this перенаправляет на другой конструктор, который будет вызывать base.

Ответ 2

Ты не можешь и не можешь. Вы можете перенаправить вызов конструктора другому конструктору того же класса на :this(...). Последний конструктор в этой цепочке должен будет инициализировать базу либо неявно, либо явно посредством :base(...)

Предположим, что класс A имеет два конструктора. Один инициализирует базу с помощью :base(2), а другой - с помощью :base(3). Если первому конструктору было разрешено также указать :this (/*call the other ctor*/), как должна быть инициализирована база: с 2 или 3? Вот почему эти вещи не разрешены

Ответ 3

Это похоже на то, что вы хотите:

public partial class TrackTyped : Component
{
    IContainer components = null;

    public TrackTyped()
        : base()
    {
        InitializeComponent();
    }

    public TrackTyped(IContainer container)
        : this()
    {
        container.Add(this);
    }
}

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

И вы правильно читаете спецификацию: она должна быть той или иной.

Ответ 4

это то, что вы ищете?

public partial class TrackTyped : Component
{
    IContainer components = null; 
    public TrackTyped() : base()
    {
        // logic for InitializeComponent() here
    } 

    public TrackTyped(IContainer container) : this()
    {
        container.Add(this)
    }
}

btw: что интересное использование для второго ctor:

var a = TrackTyped(container);

Интересно, удастся ли удалить второй ctor и сделать это? (тот же конечный результат)

container.Add(new TrackTyped());