Вопрос конструктора C # - PullRequest
       28

Вопрос конструктора C #

1 голос
/ 14 апреля 2010

У меня вопрос конструктора для C #.

У меня есть этот класс:

public partial class Signature : Form, ISignature
{
    private readonly SignatureMediator mediator;

    public Signature(SignatureMediator mediator)
    {
        this.mediator = mediator;
        InitializeComponent();
    }

    .... more stuff
 }

Я хочу построить этот класс так:

    public SignatureMediator(int someValue, int otherValue, int thirdValue)  
       : this(new Signature(this), someValue, otherValue, thirdValue)
    // This is not allowed --^
    {
        // I don't see anyway to get this in to the ":this" part.
        //Signature signature = new Signature(this);

    }            


    public SignatureMediator(ISignature form, int someValue, int otherValue, int thirdValue)
    {
        SigForm = form;
        SomeValue= someValue;
        OtherValue= otherValue;
        ThirdValue= thirdValue;
    }

: this( new SignatureThis(this) не допускается (this, используемый в конструкторе, не допускается).

Есть ли способ настроить это без дублирования присваивания значений int?

Ответы [ 4 ]

4 голосов
/ 14 апреля 2010

Как насчет того, чтобы заставить второй конструктор создать Signature из this, если параметр ISignature равен null, в противном случае используется предоставленный ISignature? Затем вы можете передать null из первого конструктора, чтобы получить желаемое поведение.

public SignatureMediator(int someValue, int otherValue, int thirdValue)  
   : this(null, someValue, otherValue, thirdValue)
{
}            

public SignatureMediator(ISignature form, int someValue, int otherValue, int thirdValue)
{
    if (form == null)
    {
        SigForm = new Signature(this);
    }
    else
    {
        SigForm = form;
    }

    SomeValue = someValue;
    OtherValue = otherValue;
    ThirdValue = thirdValue;
}
2 голосов
/ 14 апреля 2010

Вы определенно не можете использовать this внутри вызова цепочки конструктора, поэтому вам придется вызывать его в теле конструктора. Самый простой способ - извлечь общий код инициализации в отдельный метод, например так:

public SignatureMediator(int someValue, int otherValue, int thirdValue)  
{
    Initialise(someValue, otherValue, thirdValue)
    SigForm = new Signature(this);
}            


public SignatureMediator(ISignature form, int someValue, int otherValue, int thirdValue)
{
    Initialise(someValue, otherValue, thirdValue)
    SigForm = form;
}

private void Initialise(int someValue, int otherValue, int thirdValue)
{
    SomeValue= someValue;
    OtherValue= otherValue;
    ThirdValue= thirdValue;
}

Если создание объекта Signature действительно дешево, вы можете избежать использования дополнительного метода и просто вызвать второй конструктор для вызова первого, перед тем как перезаписать значение SigForm, которое он создает, переданным значением.

1 голос
/ 14 апреля 2010

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

Почему бы не передать посредника в Signature так, как это предлагает классический шаблон GoF? Ваши клиенты создают посредник, затем они передают посредник конструкторам каждого из объектов, между которыми посредник проходит. Если это слишком подвержено ошибкам, ваши объекты могут быть построены с использованием Builder или, возможно, фабричных методов.

0 голосов
/ 14 апреля 2010

Вы не можете вызвать "this" в качестве аргумента для того же самого, так как объект не создан. Вместо этого вы должны были бы связать свою конструкцию:

public SignatureMediator(int w, int x, int y, int z)  
   : this(x,y,z)
...