2011-01-31 14 views
6

Wydaje się, że nie ma składni języka dla określenia zarówno konstruktora this(), jak i base(). Biorąc pod uwagę następujący kod:Konstruktory this() i base() w języku C#

public class Bar : Foo 
{ 
    public Bar() 
     :base(1) 
     //:this(0) 
    { } 
    public Bar(int schmalue) 
     :Foo(1) 
    { 
     //Gobs of initialization code 
     ... 
     Schmalue = schmalue; 
    } 

    public int Schmalue { get; private set; } 
} 

public class Foo 
{ 
    public Foo() 
    { 
     Value = 0; 
    } 

    public class Foo(int value) 
    { 
     Value = value; 
    } 

    public int Value { get; private set; } 
} 

kompilator daje mi błąd informujący, że „{” oczekiwano kiedy odkomentowanie: ta (0) połączenia. Jest to uciążliwe, ponieważ powoduje, że koduję swój kod w prywatnej metodzie, kiedy ta funkcja została wyraźnie przewidziana, aby temu zapobiec.

Czy robię to po prostu źle? Nie próbowałem żadnego separatora, średnika, przecinka ... Wygląda na to, że był to tylko niedopatrzenie ze strony zespołu programistów. Interesuje mnie, dlaczego zostało to pominięte, jeśli robię coś niewłaściwego lub jeśli ktoś ma dobre sugestie co do alternatyw.

+1

prawdopodobny duplikat [Calling Overriden Constructor i Base Constructor w C#] (http://stackoverflow.com/questions/335286/calling-overriden-constructor-and-base-constructor-in-c) – Oded

+2

Dziękuję wszystkim odpowiedzi. W gruncie rzeczy problem polega na tym, że ten() może również wywoływać inny podstawowy konstruktor. – Sprague

Odpowiedz

8

Można to osiągnąć poprzez wywołanie konstruktora bazowego na końcu łańcucha:

public Bar(): this(0) {} 
public Bar(int schmalue): base(1) { 
    // ... initialize 
} 
+0

Dziękuję, to jest odpowiedź. Wiele innych po tym, jak powiedziałeś podobne rzeczy (niektóre bardziej wyraźnie), ale to na pewno to. – Sprague

3

Nie, można łączyć się tylko z jednym konstruktorem - innym konstruktorem tej samej klasy lub konstruktorem podstawowym.

Nie jest jasne, co próbujesz zrobić. Zazwyczaj uważam, że warto utworzyć jeden "podstawowy" konstruktor w klasie pochodnej: wszystkie inne konstruktory w klasie pochodnej używają "tego", aby wywołać pierwotny, który wywołuje "base", aby wywołać odpowiedni konstruktor podstawowy.

Mimo, że model nie pasuje każdy scenariusz - w szczególności, gdy chcesz wywołać różne konstruktorów bazowych pochodzących od różnych producentów - to zwykle dobry model.

1

W twoim projekcie nie widzę wielu typowych rzeczy między klasami Bar i Foo. Dlaczego Foo pochodzi od Bar, gdy ponownie wdrażasz wszystko? Obie klasy mają właściwość całkowitą z publicznym programem pobierającym i prywatnym ustawiaczem, a obie klasy mają domyślne konstruktory i konstruktor umożliwiający zainicjowanie właściwości liczby całkowitej. Dlaczego więc te dwie klasy istnieją?

0

Drugi konstruktor w barze jest po prostu błędne. Spróbuj:

public Bar(int schmalue) 
    :base(1) //would call Foo(1) 
{ 
    //Gobs of initialization code 
    ... 
    Schmalue = schmalue; 
} 

Komentarz w pierwszej ctor wydaje się oznaczać coś takiego

  • initialize Bar z schmalue = 0

  • wezwanie baza konstruktor Foo z value = 1

Dobrze?

Aby to zrobić, należy wymienić drugi konstruktor i po prostu dodać kolejny (prywatny) konstruktor, który może obsłużyć obie wartości

public Bar(int schmalue) 
    :this(1, schmalue) //would call Bar(1, schmalue) 
{ 
} 

private Bar(int value, int schmalue) 
:base(value) 
{ 
    //Gobs of initialization code 
    ... 
    Schmalue = schmalue; 
} 
3

Zastanów się, co by było, gdyby można nazwać zarówno this i base jako konstruktorów w jednym konstruktora. Załóżmy, że najpierw zostanie wywołany konstruktor bazowy. Następnie zostanie wywołany konstruktor this - który sam wywoła konstruktor bazowy. Zatem klasa bazowa byłaby tworzona dwukrotnie. To łamie semantykę konstruktorów - mianowicie, że obiekt jest budowany raz.

Jako takie, wywoływanie zarówno base, jak i this jest zabronione. Pozwól, aby Twój delegowany konstruktor wywoływał bazę z określonymi parametrami, jeśli to konieczne.