Il mio problema qui è che vorrei passare un oggetto a una classe derivata, ma deve essere fatto prima del costruttore della classe base, poiché la classe base chiamerà immediatamente il derivato il metodo Start()
della classe che utilizza l'oggetto.Esegui un costruttore derivato prima del costruttore base in C#
Ecco un estratto dalla classe base, (rinominata da BarcodeScanner per comodità).
public abstract class MyBase
{
public MyBase()
{
if (Initialize())
this.Start();
}
public abstract bool Initialize();
public abstract void Start();
}
Ecco la classe derivata che sto creando.
class MyDerived : MyBase
{
private string sampleObject;
public MyDerived (string initObject)
{
sampleObject = initObject;
}
public override bool Initialize()
{
return GetDevice();
}
public override void Start()
{
Console.WriteLine("Processing " + sampleObject.ToString());
}
}
Dubito che è possibile eseguire C# eseguire un costruttore derivato prima del costruttore base; quindi sto solo cercando una soluzione per passare un oggetto alla classe derivata prima che l'oggetto venga usato.
Ho ottenuto questo problema inserendo il blocco Initialize/Start if nel costruttore MyDerived
. Tuttavia, ci sono altre classi derivanti dalla classe base; quindi ho finito per dover ripetere questo blocco di Initialize/Start code in ogni classe derivata. Mi piacerebbe vedere un'alternativa alla modifica della classe base.
Bene, è possibile creare metodi di inizializzazione/avvio di sovrascrittura vuoti e spostare tali codici in metodi derivateInitialize/derivedStart, quindi nel costruttore derivato, chiamare 'if (derivedInitialize()) derivedStart()'. Non ci possono essere soluzioni eleganti, ma ci sono ancora altri modi. – James
Mentre è spesso utile per un framework cercare di impedire l'esposizione di oggetti costruiti in modo incompleto, ci sono momenti in cui sarebbe più utile per una classe avere accesso a tali oggetti, con l'avvertenza che deve essere preparato per trattare con oggetti parzialmente costruiti. Ad esempio, se una classe incapsulerà un oggetto 'IDisposable' la cui durata corrisponderà al proprio, sarebbe conveniente usare un inizializzatore di campo per configurarlo; purtroppo in C# non c'è un modo pulito per farlo in modo sicuro. Se il costruttore della classe base getta, nulla sarà in grado di ottenere un riferimento alla cosa che ha bisogno di essere smaltita. – supercat