Dovresti scegliere tra init in declaration o constructor, non entrambi.
In una lingua con un costruttore predefinito in cui non è necessario fornire esplicitamente un costruttore se il valore predefinito è tutto ciò che serve, una dichiarazione init può andare bene. Non appena hai bisogno di un costruttore esplicito con parametro, tendo a spostare tutto su costruttore / i, per garantire che il comportamento di init sia in un unico posto.
Troppo onesto, non uso quasi mai la dichiarazione init, ma potrebbe essere solo una preferenza. Il mio vantaggio è che tutto il comportamento di init è sempre incapsulato nei costruttori: non devo mai guardare in due punti (o mancarlo nella dichiarazione delle variabili).
Ri:
"it is probable that I introduce other constructors where x may not be initialized"
Dovresti sempre codificare i costruttori per riutilizzare un altro costruttore come appropriato. Per esempio. nel tuo esempio, aggiungere un altro costruttore con parametri add aggiuntivi potrebbe essere fatto in questo modo:
class Foo
{
public X x;
public Y y;
public Foo(X _x)
{
x = _x ?? new X();
}
//WRONG!
public Foo(X _x, Y _y)
{
x = _x;
y = _y;
}
//Right
public Foo(X _x, Y _y)
{
this(_x);
y = _y ?? new Y();
}
}
Infine, quando si delegano a un altro costruttore, si preferisce sempre this () a base () (super () in Java) poiché aggiunge alla coesione locale. Per maggiori dettagli su this () vs base () in C #, vedi per es. link