Qual è una buona convenzione di denominazione per i tipi generici in C #? [chiuso]


16

Ho deciso di porre questa domanda qui anziché in overflow dello stack perché è piuttosto soggettivo.

In C #, in genere vedo tipi generici con nomi molto poveri. In particolare, "T" è comunemente usato ma non è un nome significativo da solo. Per esempio:

class Fruit<T>
{
    T fruit;
}

Mentre questo è l'approccio tipico, qualcuno consiglierebbe di non farlo? E in caso affermativo, quale sarebbe una ragionevole convenzione di denominazione per i tipi generici nel contesto di C # per funzioni e classi generiche?

Nel mio esempio precedente, supponiamo che il tipo generico Tdebba essere sempre un tipo di frutto, come Appleo Orange. Il tipo Tdeve rendere ovvio che si tratta di un tipo di frutto, quindi forse sarebbe un nome migliore FruitType, quindi finiamo con:

class Fruit<FruitType>
{
    FruitType fruit;
}

Questo è solo per darti un'idea di quello che sto cercando. Qual è una "regola empirica" ​​accettabile per questo problema?


3
Questa non è una domanda costruttiva. Riceverà risposte solo con lo stile preferito del poster.
Michael K,

1
Dai un'occhiata ai vincoli, considerando il tuo esempio: msdn.microsoft.com/en-us/library/d5x73970.aspx#Y426
Matthieu

2
@Michael ci saranno un certo numero di risposte, e la risposta accettata sarà la preferita di Robert, ma verranno votate varie altre risposte.
Stuper:

5
@Michael Una domanda soggettiva ottiene una risposta soggettiva. La domanda è ancora costruttiva perché funge da punto di riferimento per chiunque desideri una varietà di idee / soluzioni a questo particolare problema. Quello che contrassegno come risposta non rappresenta l'unico e solo utile pezzo di informazione.
void.pointer

Forse trasformarlo in un wiki della comunità, come una buona risorsa, sebbene soggettiva?
Tylermac,

Risposte:


22

È davvero soggettivo ... ish .
Come alcuni ritengono che isia perfettamente valido per una variabile for loop, alcuni pensano che Tsia perfettamente valido per un segnaposto di tipo in una classe generica.

Personalmente sposo questo approccio, è una convenzione comune e la gente generalmente sa cosa intendi.

Laddove il tipo fosse significativo, utilizzerei un nome significativo, ma generalmente lo inizio con T. Di recente ho sviluppato una classe di dizionario generica (non chiedere) e la dichiarazione era

public class Dictionary<TKey, TValue>

Tuttavia, per qualcosa come una Tupla, in cui i tipi sono essenzialmente privi di significato, considero perfettamente accettabile quanto segue.

public class Tuple<T1, T2, T3>

2
Non lo trovo affatto soggettivo. ie Tfunziona, e questo è misurabile in linea di principio (cioè è misurabile se la comprensione del codice sorgente aumenta se, per esempio, gli indici di loop ottengono identificatori diversi). Solo perché è difficile da misurare non significa che dobbiamo etichettare l'etichetta "soggettiva" su tutto. Dato l'ampio uso senza ovvi problemi, è abbastanza ragionevole dire anche senza misurare che in effetti funziona.
Konrad Rudolph,

2
@Konrad: hai ragione. . . tuttavia la domanda non è etichettata come soggettiva, chi chiede ammette che è un argomento soggettivo supponendo che le persone tendano ad avere le proprie preferenze sulle convenzioni di denominazione. Quindi, sebbene la domanda possa non essere soggettiva (e di fatto non lo è in quanto esiste una risposta corretta, ovvero la risposta che si collega alla linea guida ufficiale di Microsoft), l'argomento è soggettivo, poiché sono sicuro che qualcuno pubblicherà un " ie Tsono cattivi . Non si deve mai usare mai nomi di singole lettere" digitare la risposta. Ho aggiunto un ish per aiutare a soddisfare tutti :)
Binary Worrier

1
Penso che i soli commenti aggiunti a questo post lo rendano una risposta molto preziosa, sebbene la risposta stessa sia molto utile. Tha senso quando parliamo di un tipo senza vincoli, TFruitha senso perché mi dice "Qualsiasi tipo con il vincolo che è un frutto". Questa sembra una buona "regola empirica" ​​per la denominazione di parametri di tipo generico. Grazie!!
void.pointer

1
Solo per notare, questo è in linea con le Linee guida di progettazione .NET Framework per sviluppatori di librerie da MSDN. Vedi: Nomi dei parametri di tipo generico .
Concedi Thomas il

7

Penso che tu abbia ragione, anche se T è diventato abbastanza uno standard. Probabilmente proviene dai vecchi tempi di C ++ e dalla dicitura "di tipo T". Considero una buona pratica il più descrittivo possibile, ma è soggettivo.

Puoi scegliere T come prefisso, proprio come molte persone scelgono I per le interfacce. così

class Juice<TFruit> where TFruit...

sarebbe un buon nome secondo la mia modesta opinione. Preferisco i prefissi ai suffissi nella maggior parte dei casi, poiché è immediatamente chiaro cosa vedi quando ci si imbatte in esso ed è più facile cercare con cose come Intellisense. È buona norma anche per i controlli UI, quando molto probabilmente conosci sempre il tipo (ad esempio TextBox) ma non sei sicuro al 100% del nome descrittivo che gli hai dato.

Il lato negativo è che sembra brutto quando il tipo stesso inizia con T. Quindi penso che sarebbe una buona cosa aggiungere il tipo generico in casi speciali, come quello qui sotto.

class SomeAlgorithm<TypeT> where TypeT : Type

Si prega di notare che questa è solo la mia opinione e altamente soggettiva. Ma penso di avere un punto secondario con la preferenza del prefisso al suffisso.


L'uso del Tprefisso per i parametri di tipo e Iper i nomi delle interfacce è esplicitamente richiesto ( regole " DO ...") nelle Linee guida per la progettazione del framework.
Richard,

1
È discutibile ciò che l'utilizzo TFruitqui porta al tavolo T. Usare un nome come TTypeo TypeTè sicuramente una sciocchezza. Non aggiunge alcuna informazione oltre al solo T. Vengono fornite esattamente le stesse informazioni.
Konrad Rudolph,

@Konrad Rudolph: guarda attentamente il mio esempio di TypeT, copre un caso speciale quando si tratta di System.Type. Penso che i miei nomi abbiano un'entropia superiore rispetto all'uso di T per il tipo, soprattutto se anche il generico è vincolato.
Falcon,

7

Microsoft ha una linea guida ufficiale per i generici: nomi di classi, strutture e interfacce (citati qui , e in forma di libro: Linee guida per la progettazione di strutture ).

Per quanto riguarda la tua domanda specifica, dice:

Assegna un nome a parametri di tipo generico con nomi descrittivi, a meno che un nome di una sola lettera non sia completamente autoesplicativo e un nome descrittivo non aggiunga valore.

IDictionary<TKey, TValue> 

è un esempio di un'interfaccia che segue questa linea guida.

Prendi in considerazione l'utilizzo della lettera T come nome del parametro di tipo per i tipi con un parametro di tipo a lettera singola.

Prefisso i nomi dei parametri del tipo descrittivo con la lettera T.

Considerare di indicare i vincoli posti su un parametro di tipo nel nome del parametro. Ad esempio, un parametro vincolato a ISession può essere chiamato TSession.


Un riferimento migliore sarebbe il libro delle Linee guida per la progettazione del framework o il (sommario) su MSDN, in particolare Nomi di classi, strutture e interfacce .
Richard,

@Richard: aggiustata la mia risposta considerando il tuo commento, grazie!
Matthieu,

2

Il punto centrale della generica è delegare la funzionalità: la classe generica fa una cosa, il suo argomento ne fa un'altra. L'esempio del libro di testo è una raccolta generica: la raccolta memorizza le "cose", ma non importa cosa siano queste cose. Un nome generico (sic!), Quindi, ha una certa logica ad esso - non vogliamo che sia descrittivo, perché non c'è niente da descrivere se non "è l'argomento di tipo generico", che il nome Tracchiude in modo esaustivo (considerando la convenzione). Essere descrittivi è positivo, ma essere eccessivamente descrittivi suggerisce restrizioni che non esistono.

A volte, tuttavia, una classe o un metodo generico ha più di un parametro di tipo e, a questo punto, ha senso dare loro nomi più descrittivi, in modo che il loro ruolo diventi ovvio. Un buon esempio sarebbe per un tipo di raccolta valore-chiave, in cui sia la chiave che il valore sono generici; chiamarli Te S(o Qqualunque cosa) sarebbe meno utile che chiamarli, diciamo, KeyTypee ValueType, oe TKeye TVal.


1

La risposta è davvero soggettiva. Tuttavia, ha il merito come una domanda, poiché il codice dovrebbe auto-documentarsi e potremmo forse imparare tutti alcuni modi migliori per farlo.

Di seguito sono riportate le convenzioni che ho imparato e seguito:

  • I parametri di tipo generico non dovrebbero mai essere scambiati per classi concrete. Questo in genere incoraggia una prefazione di Tqualunque cosa segua, proprio come le interfacce sono generalmente precedute da I.

  • Un singolo parametro di tipo generico su una classe o un metodo deve essere generalmente etichettato T. Questa è una convenzione quasi universalmente compresa che risale ai modelli C ++.

  • Più parametri di tipo generico sulla stessa classe o dichiarazione del metodo dovrebbero iniziare tutti con T, ma devono essere differenziati da alcuni mezzi concisi ma comprensibili. TIne TOut, ad esempio, sono GTP comuni e ben compresi per un metodo che accetta un input generico fortemente tipizzato e produce un output generico fortemente tipizzato.

  • Più tipi differenziati ma non significativi, come per una classe contenente come .Tup di Net. O tipi delegati come Func, Predicate e Action, possono essere etichettati T1, T2, T3, ecc. Tuttavia, dichiarazioni GTP "notevoli" (aventi uno scopo preciso e / o restrizioni di tipo molto specifiche) dovrebbero avere qualcosa di più descrittivo.

  • Un singolo tipo generico su un metodo, che differisce dal tipo generico di una classe contenente, può seguire la regola precedente per quanto riguarda più tipi in una classe o metodo, O se il tipo è irrilevante diverso dall'essere diverso, può essere assegnato un diverso singola lettera, spesso Uo V. Questa è di nuovo una convenzione che risale ai modelli C ++.

  • Qualunque cosa tu scelga di fare, mantienila coerente; non etichettare un GTP per una classe Te la successiva TParam, a meno che la seconda classe sia nidificata nel primo rendendo Tnon disponibile per l'uso nel secondo.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.