Come generalizzare quale delegato viene utilizzato da un'interfaccia

0

Attualmente ho il seguente set in cui ho 2 o 3 classi che implementano IZoneController e ho una serie di condizioni che determinano quale funzione devono eseguire quando vengono chiamate. Ho iniziato per la prima volta a definire circa 20 classi per ciascuna funzione, ma erano davvero scarse e ho pensato che avrei potuto trovare un modo migliore.

Ora ho la mia soluzione attuale, che assomiglia a questa.

public IZoneController IdentifyZone(object conditionDeterminer, IItemContainer container)
{
    Func<object, IItemContainer, List> itemAction;
    if(condition1(conditionDeterminer))
    {
        itemAction = AlterValue;
        var zController = new CCell(itemAction, container);

    }
    elseif(condition2(conditionDeterminer))
    {
        itemAction = AlterName;
        var zController = new CRange(itemAction, container);
    }

...

    elseif(condition_n(conditionDeterminer)){...}
    else(){...}
    return zController;
}

dove tutte le mie funzioni "Alter" hanno lo stesso modello,

List AlterValue(object toCast, IItemContainer container)
{
    return container.SetValue((decimal) toCast);
}

List AlterName(object toCast, IItemContainer container)
{
    return container.SetName((string) toCast);
}

...

List AlterX(object toCast, IItemContainer container)
{
    return container.SetX((xType) toCast);
}

Ora ecco la grande domanda. Mi stavo chiedendo se c'è un modo di scrivere una singola funzione in cui posso definire quale metodo voglio chiamare dall'interfaccia IItemContainer, così come il tipo a cui voglio lanciare l'oggetto. Sarebbe qualcosa di simile,

Func<object, IItemContainer, List> CreateItemAction<T>(Func<T, List> containerFunction)
{
}

Non sono esattamente sicuro di come verrebbe effettivamente chiamato, ma forse qualcosa del tipo

delegate List itemAlteration = IItemContainer.SetX;
itemAction = CreateItemAction<xType>(itemAlteration);

o

delegate List itemAlteration = container.SetX;
itemAction = CreateItemAction<xType>(itemAlteration);

E non riesco proprio a capire cosa dovrebbe andare nei meandri della funzione CreateItemAction per farlo funzionare davvero. Eventuali osservazioni, richieste di ulteriori informazioni o indicazioni su dove e perché questo codice è strutturato male sarebbero molto apprezzate.

Come nota a margine, ho la sensazione che tutto il cast dall'oggetto alla stringa / decimale sia piuttosto maleodorante, ma è l'input dell'utente, e ad un certo punto implementerò un po 'di gestione degli input non validi. Dovrei semplicemente spostare la parte cast nelle classi effettive che implementano IItemContainer?

    
posta Daniel Shank 03.10.2017 - 16:32
fonte

1 risposta

0

Pensa di sbarazzarti dell'interfaccia e semplicemente di usare i delegati. La funzione da eseguire deve essere specificata per nome quando si crea il delegato. Non è necessario nient'altro che nominare la funzione e passarla a un oggetto di archiviazione che ha un parametro di tipo generico per il parametro function. Dico sbarazzarsi dell'interfaccia perché non serve a nulla, i delegati sono equivalenti. È possibile utilizzare un delegato (non generico) come oggetto di archiviazione e il riflesso per determinare il tipo di parametro, ma penso che sia preferibile creare una classe di archiviazione con un parametro di tipo.

Una soluzione migliore sarebbe quella di eliminare sia l'interfaccia che i delegati e utilizzare un evento. Ciò sarebbe in linea con le linee guida di progettazione del framework.

    
risposta data 04.10.2017 - 01:36
fonte

Leggi altre domande sui tag