2015-11-19 9 views
5
class Foo<T> 
{ 
    public T Bar() { /* ... */ } 
} 

Vorrei passare il nome di Bar a Type.GetMethod(string). Posso farlo come someType.GetMethod(nameof(Foo<int>.Bar)), ma quello int è completamente arbitrario qui; c'è un modo in cui posso ometterlo? Purtroppo, nameof(Foo<>.Bar) non funziona.Utilizzare nameof su un membro di una classe generica senza specificare argomenti tipo

Non è un grosso problema in questa custodia, ma se ci sono più parametri di tipo e soprattutto se hanno vincoli where allegati, la loro ortografia può diventare un'attività.

risposta

3

Il nameof documentation dice specificamente che cosa si vuole fare è non consentito, purtroppo:

Poiché l'argomento deve essere un'espressione sintatticamente, ci sono molte cose che non sono consentiti utile elencare. Il seguente è importante segnalare che gli errori producono: tipi predefiniti (ad esempio, int o void), tipi nullable (Point?), tipi di matrice (Customer[,]), tipi di puntatore (Buffer*), alias qualificato (A::B), e tipi generici non associati (Dictionary<,>), simboli di pre-elaborazione (DEBUG), ed etichette (loop:).

Il meglio che si può probabilmente fare è specificare Bar in un'interfaccia e utilizzare nameof(IFoo.Bar). Naturalmente, questa non è un'opzione se Bar include qualcosa relativo a T nella sua firma (come in questo caso specifico).


Un'altra opzione è quella di creare un'interfaccia in cui ogni T viene sostituito con object. Quindi il tipo concreto implementa esplicitamente l'interfaccia, implementando anche versioni generiche degli stessi metodi.

Questo ha un paio di aspetti negativi:

  • ingrandita della superficie API
  • Più difficile e soggetto a errori refactoring
  • Perdere a tempo di compilazione sicurezza di tipo perché un chiamante può utilizzare l'interfaccia object.

Questo probabilmente non è giustificabile solo per utilizzare nameof, ma in alcuni casi questa strategia ha senso per altri motivi. In questi casi, essere in grado di utilizzare nameof sarebbe solo un comodo bonus.

+0

"ad esempio se Bar include qualcosa relativo a T nella sua firma" che è esattamente il mio caso (modificato la domanda per includerlo). Ah bene. – dlf

+0

In questo caso, comunque, preferisco inserire solo argomenti di tipo non necessari. Per prima cosa, avere entrambe le versioni 'T' e' object' di 'Bar' lascerebbe il codice vulnerabile allo stesso tipo di bug post-ridenominazione che' nameof' è stato introdotto per risolvere in primo luogo. Se fossi disposto a tollerarlo, sarebbe più semplice fare semplicemente 'GetMethod (" Bar ")'. La vita va a vanti. :) – dlf

+0

@dlf Concordato. Ho spostato il contenuto del mio commento nella risposta per i posteri. – 31eee384

Problemi correlati