Classi derivate come valore di ritorno
-
26-09-2019 - |
Domanda
Dato queste classi C# (generate da WCF, Non posso cambiarli):
public SysState GetSysState();
public class SysState { /* nothing much here */}
public class Normal : SysState { /* properties & methods */ }
public class Foobar : SysState { /* different properties & methods */ }
Il mio codice (attualmente):
SysState result = GetSysState();
if (result is Normal) HandleNormal((Normal) result);
if (result is Foobar) HandleFoobar((Foobar) result);
La mia domanda: Continuo a sentire che mi manca qualcosa di ovvio, che non dovrei aver bisogno di controllare esplicitamente il tipo.Sto vivendo un momento da senior?
Soluzione
Utilizza un metodo virtuale.Inserisci il tuo codice nelle classi su cui operano, non in un codice che ottiene un riferimento alla classe.
public class SysState {
/* nothing much here, except...: */
public abstract virtual void DoSomething();
}
public class Normal : SysState {
/* properties & methods */
public override void DoSomething()
{
// ...
}
}
public class Foobar : SysState {
/* different properties & methods */
public override void DoSomething()
{
// ...
}
}
SysState result = SomeFunctionThatReturnsObjectDerivedFromSysState();
result.DoSomething();
Questo eseguirà il metodo DoSomething della classe derivata.Questo si chiama polimorfismo ed è il più naturale (e alcuni sostengono l’unico corretto) uso dell'eredità.
Tieni presente che SysState.DoSomething non deve essere astratto affinché funzioni, ma deve essere virtuale.
Altri suggerimenti
Potresti provare a combinare handleX
e posizionamento Handle
In SysState
e sovrascrivendolo in entrambi Normal
E Foobar
per eseguire compiti specifici.Potrebbe non essere la soluzione perfetta, ma sembrerebbe relativamente carina.Se devi inserire dati da altre fonti, passarli come parametri?
public class SysState
{
public bool Process(Information info)
{
return ( info.Good );
}
}
public class Normal
{
public bool Process(Information info)
{
return doStuff();
}
}
public class Foobar
{
public bool Process(Information info)
{
return diePainfully();
}
}
Ovviamente solo un esempio, non sapendo cosa fanno HandleNormal e HandleFoobar, ma potrebbe funzionare bene.