Che cos'è l'abuso di generici?

36

Durante la revisione di alcuni codici, ho notato l'opportunità di modificarlo per utilizzare i generici. Il codice (offuscato) ha il seguente aspetto:

public void DoAllTheThings(Type typeOfTarget, object[] possibleTargets)
{
    var someProperty = typeOfTarget.GetProperty(possibleTargets[0]);
    ...
}

Questo codice potrebbe essere sostituito da generici, in questo modo:

public void DoAllTheThings<T>(object[] possibleTargets[0])
{
    var someProperty = type(T).getProperty(possibleTargets[0]);
    ...
}

Nella ricerca dei vantaggi e delle carenze di questo approccio ho trovato un termine chiamato abuso generico . Vedi:

La mia domanda si divide in due parti:

  1. Ci sono dei vantaggi nel passare a generici come questo? (Prestazioni? Leggibilità?)
  2. Che cos'è l'abuso generico? E usa un generico ogni volta che c'è un parametro di tipo e un abuso ?
posta SyntaxRules 07.02.2018 - 18:23
fonte

4 risposte

88

Quando i generici vengono applicati in modo appropriato, rimuovono rimuovono il codice anziché semplicemente riorganizzandolo. In primo luogo, il codice che i generici riescono meglio a rimuovere sono typecasts, reflection e digitazione dinamica. Pertanto l'abuso di generici potrebbe essere definito genericamente come la creazione di codice generico senza una significativa riduzione di typecasting, reflection o digitazione dinamica rispetto a un'implementazione non generica.

Riguardo al tuo esempio, mi aspetterei un uso appropriato dei generici per cambiare il object[] in un T[] o simile, ed evitare del tutto Type o type . Ciò potrebbe richiedere un refactoring significativo altrove, ma se l'uso di generici è appropriato in questo caso, dovrebbe finire più semplice quando hai finito.

    
risposta data 07.02.2018 - 19:59
fonte
5

Userei la regola della non-assurdità: Generics, come tutti gli altri costrutti di programmazione, esiste per risolvere un problema . Se non c'è alcun problema da risolvere per i generici, utilizzarli è un abuso.

Nel caso specifico dei generici, esistono per lo più astratti dai tipi concreti, permettendo che le implementazioni del codice per i diversi tipi siano piegate insieme in un modello generico (o qualsiasi altra cosa si chiami nella tua lingua). Ora supponiamo di avere un codice che utilizza un tipo Foo . Potresti sostituire quel tipo con un generico T , ma se hai sempre bisogno che quel codice funzioni con Foo , semplicemente non c'è altro codice con cui puoi piegarlo insieme. Quindi, non esiste alcun problema da risolvere, quindi l'indirezione di aggiungere il generico servirebbe solo a ridurre la leggibilità.

Di conseguenza, suggerirei di scrivere semplicemente il codice senza usare i generici, finché non vedrai la necessità di introdurli (perché hai bisogno di una seconda istanziazione). Quindi, e solo allora, è il momento di ridefinire il codice per utilizzare i generici. Qualsiasi uso prima di quel punto è un abuso nei miei occhi.

Sembra un po 'troppo pedante, quindi lascia che ti ricordi:
Non c'è una regola senza eccezioni nella programmazione. Questa regola inclusa.

    
risposta data 08.02.2018 - 00:02
fonte
0

Il codice sembra strano. Ma se lo chiamiamo, sembra più bello specificare il tipo come generico.

link

Personalmente non mi piacciono queste contorsioni che rendono il codice chiamante bello. per esempio l'intera cosa "fluente" e i metodi di estensione.

Ma devi ammettere che ha un seguito popolare. ad esempio, microsoft lo usa in unità

container.RegisterType<IInterface,Concrete>()
    
risposta data 07.02.2018 - 18:53
fonte
0

Per me sembra che tu fossi sulla strada giusta qui, ma non hai finito il lavoro.

Hai preso in considerazione la possibilità di modificare il parametro object[] in Func<T,object>[] per il passaggio successivo?

    
risposta data 01.03.2018 - 21:46
fonte

Leggi altre domande sui tag