L'uso di "è" e "come" in più condizioni

5

Di recente, ho pensato all'uso di as , is e cast diretto in C #.

Logicamente, è un'idea migliore da usare:

 var castedValue = value as type;
 if (null != castedValue)
 {
     // Use castedValue.
 }

di:

if (value is type)
{
    var castedValue = (type)value;
    // Use castedValue.
}

Ma ho ancora problemi con questo tipo di pattern:

if (value is Implementation1)
{
    var castedValue = (Implementation1)value;
    // Use castedValue in a first way.
}
else if (value is Implementation2)
{
    var castedValue = (Implementation2)value;
    // Use castedValue in a second way.
}
else if (value is Implementation3)
{
    var castedValue = (Implementation3)value;
    // Use castedValue in a thrid way.
}
// And so on...

Come posso migliorare questo codice per evitare di trasmettere due volte quando è OK, ed è davvero necessario eseguire il cast due volte?

Non voglio rendere il codice illeggibile, ma l'idea non è quella di testare un cast se uno precedente è riuscito.

Ho avuto diverse idee per risolvere questo problema, ma nessuno di loro sembra davvero soddisfare le condizioni ...

Modifica

Ecco un caso che ho ... C'è questo oggetto che viene creato da una parte inferiore del codice su cui non ho il controllo. Questo oggetto può essere di diversi tipi ereditati. Nel mio livello, voglio creare un oggetto specifico a seconda di questo tipo. Ho questa classe di costruttore:

public static IHighLevelObject MakeHighLevelObject(LowLevelObject lowLevelObject)
{
    IHighLevelObject highLevelObject;

    if (lowLevelObject is LowLevelObject1)
    {
        highLevelObject = new HighLevelObject1((LowLevelObject1)lowLevelObject);
    }
    else if (lowLevelObject is LowLevelObject2)
    {
        highLevelObject = new HighLevelObject2((LowLevelObject2)lowLevelObject);
    }
    else if (lowLevelObject is LowLevelObject3)
    {
        highLevelObject = new HighLevelObject3((LowLevelObject3)lowLevelObject);
    }
    // And so on...

    return highLevelObject;
}

Come posso risolvere questo caso?

    
posta clemchen 28.02.2013 - 12:38
fonte

2 risposte

15

Questo tipo di codice suggerisce problemi di progettazione che è necessario affrontare prima.

Il codice si rompe Principi Open-Closed e Principio di sostituzione di Liskov : ogni volta che è necessario aggiungere un nuovo tipo di implementazione per estendere la funzionalità, è necessario modificare questa classe. Dovresti progettare la tua soluzione in modo che la ramificazione logica avvenga tramite un approccio generalizzato, ad es. usando il polimorfismo. Dato che hai fornito una descrizione molto generale, è difficile suggerire una soluzione appropriata per il tuo problema.

    
risposta data 28.02.2013 - 12:46
fonte
5

Supponendo che il polimorfismo non sia da nessuna parte sul radar, puoi usare più return s e usare as .

public static IHighLevelObject MakeHighLevelObject(LowLevelObject lowLevelObject)
{
    LowLevelObject1 object1 = lowLevelObject as LowLevelObject1;
    if (object1 != null)
    {
        return new HighLevelObject1(object1);
    }
    LowLevelObject2 object2 = lowLevelObject as LowLevelObject2;
    if (object2 != null)
    {
        return new HighLevelObject2(object2);
    }
    // And so on...
}

La tua classe LowLevelObject potrebbe avere solo un metodo virtuale ToHighLevelObject che ogni sottoclasse sovrascrive ed evitare questa cattiveria all'inizio.

    
risposta data 28.02.2013 - 22:37
fonte

Leggi altre domande sui tag