Classes derivadas como valor de retorno
-
26-09-2019 - |
Pergunta
Dado Essas classes C# (geradas pelo WCF, Eu não posso mudar estes):
public SysState GetSysState();
public class SysState { /* nothing much here */}
public class Normal : SysState { /* properties & methods */ }
public class Foobar : SysState { /* different properties & methods */ }
Meu código (atualmente):
SysState result = GetSysState();
if (result is Normal) HandleNormal((Normal) result);
if (result is Foobar) HandleFoobar((Foobar) result);
Minha pergunta: Fico sentindo faltando algo óbvio, que não preciso verificar o tipo de maneira explicitamente. Estou tendo um momento sênior?
Solução
Use um método virtual. Coloque seu código nas classes em que eles operam, não em algum código que obtenha uma referência à 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();
Isso executará o método do dosomething da classe derivada. Isso é chamado de polimorfismo e é o mais natural (e alguns argumentariam o único correto) uso da herança.
Observe que o sysstate.Dosoming não precisa ser abstrato para que isso funcione, mas precisa ser virtual.
Outras dicas
Você pode tentar combinar handleX
e colocando Handle
dentro SysState
e ultrapassá-lo em ambos Normal
e Foobar
para executar tarefas específicas. Pode não ser a solução perfeita, mas pareceria relativamente arrumada. Se você precisar inserir dados de outras fontes, passe -os como parâmetros?
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();
}
}
Obviamente, apenas um exemplo, sem saber o que o Handlenormal e o Handlefoobar fazem, mas poderia funcionar bem.