Il problema qui è che o doStuff
o SuperClass
(o entrambi) è troppo generico per descrivere accuratamente cosa dovrebbe essere fatto in questa azione (metodo). L'unica ragione per cui dovresti controllare i tipi qui è che sono progettati male per cominciare e non offrono abbastanza contratti per intraprendere quell'azione.
Dato che non dici cosa si riferisce effettivamente a doStuff
o SuperClass
, diciamo che è log(LogEventBase logEvent)
. Osservando questa firma del metodo, ci sono lacune di informazioni che devono essere riempite.
- Cosa viene effettivamente scritto nel log da
logEvent
?
- Dove ci connettiamo?
- Che cosa significa essere
LogMessageBase
?
Qui ci sono una serie di altre potenziali domande senza risposta, ma potresti pensare che la soluzione sia basare il metodo sull'effettivo Type
di LogEventBase
:
public void log(LogMessageBase logEvent)
{
switch (logEvent.GetType()):
case BusinessLogicLogEvent:
logToUserInterface(logEvent);
case ErrorLogEvent:
logToErrorLogs(logEvent);
...
Questo è cattivo !
Se è stato progettato correttamente, la risposta a tali domande sarebbe scritta nei Tipi / metodi direttamente in un numero di modi diversi. Un esempio di uno di questi modi è con un'interfaccia meglio definita:
public ILogMessage
{
public GUID Id;
public LogLevel Level;
public string Message;
}
public void log(ILogMessage message)
{
switch (message.LogLevel):
case LogLevel.Error:
logToFile(...
// or
public void logToConsole(ILogMessage message)
{
Console.WriteLine(string.format("Message: {0}. Id: {1}",
message.Message,
message.Id);
}
Il punto è che l'interfaccia descrive un contratto per ciò che significa essere ILogMessage
, non il Tipo, che potrebbe crescere rapidamente e diventare non più possibile.
Non esiste una risposta standard per il tuo particolare problema senza conoscere i tipi di dati coinvolti. In effetti, mettere LogLevel
direttamente sull'interfaccia ILogMessage
potrebbe essere completamente sbagliato per il tuo caso d'uso. Certamente non intendo implicare che dovresti specificare un'interfaccia con una proprietà TypeName
e spostare la responsabilità lì. Quella particolare soluzione era solo lì per illustrare un esempio di risoluzione del problema (che LogMessageBase
era troppo ampio di un argomento per questo metodo) all'origine quindi non è necessario attivare il tipo per iniziare.