2012-04-26 5 views
6

Quando si tratta di metodi di estensione, i nomi di classe sembrano non fare nulla, ma fornire un raggruppamento che è ciò che gli spazi dei nomi fanno. Non appena includo lo spazio dei nomi ottengo tutti i metodi di estensione nello spazio dei nomi. Quindi la mia domanda si riduce a questo: c'è qualche valore che posso ottenere dai metodi di estensione che si trovano nella classe statica?I metodi di estensione traggono vantaggio in modo pratico dall'essere parte di una classe statica rispetto a [teoricamente] una parte di uno spazio dei nomi?

Mi rendo conto che è necessario un compilatore per inserirli in una classe statica, ma sembra che dal punto di vista organizzativo sia ragionevole che sia legale consentire i metodi di estensione da definire negli spazi dei nomi senza classi che li circondano. Riformulare la domanda di cui sopra in un altro modo: C'è qualche vantaggio pratico o aiuto in qualche scenario che ottengo come sviluppatore dal fatto che i metodi di estensione sono collegati alla classe e collegati allo spazio dei nomi?

Fondamentalmente sto solo cercando di ottenere intuizioni, conferme o intuizioni - sospetto che potrebbe essere che sia stato più semplice implementare i metodi di estensione in quel modo e non valeva il tempo di consentire l'esistenza di metodi di estensione sul loro proprio in spazi nome.

+0

Essi * potrebbero * condividere variabili di istanza statiche della classe, ovviamente ... Inoltre, tenere presente che è ancora possibile chiamare i metodi di estensione attraverso la sintassi della classe regolare. –

+3

C# è _all_ sulle classi. Lo sviluppo del linguaggio e dell'intero sistema CLR/.NET deriva dalla scuola di programmazione "avremmo preferito non avere le cose non nelle classi" ereditata da java e JVM. – Will

+1

Giriamo la domanda: come definirebbe un metodo al di fuori di un tipo? –

risposta

3

Forse troverete una risposta soddisfacente nel post sul blog di Eric Lippert Why Doesn't C# Implement "Top Level" Methods? (a sua volta richiesto dal SO in discussione Why C# is not allowing non-member functions like C++), dove (il corsivo è mio):

mi viene chiesto "Perché non C# implementare funzionalità X?" tutto il tempo. La risposta è sempre la stessa: poiché nessuno ha mai progettato, specificato, implementato, testato, documentato e spedito quella funzione. Tutti e sei di sono necessari per realizzare una funzione. Tutti costano enormi quantità di tempo, sforzi e denaro. Le funzionalità non sono a buon mercato e noi ci impegniamo molto per assicurarci di spedire solo quelle funzioni che offrono i migliori vantaggi possibili ai nostri utenti, dati i nostri budget limitati di tempo, sforzi e denaro. .

Capisco che tale risposta generale probabilmente non risolva la domanda specifica .

In questo caso particolare, il chiaro vantaggio per l'utente non era in passato pari a abbastanza grande da giustificare le complicazioni alla lingua che corrisponderebbe a . Limitando il modo in cui nidificano le diverse entità linguistiche all'interno di ogni , noi (1) limitiamo i programmi legali a uno stile comune, facilmente comprensibile allo e (2), è possibile definire le regole di "identificatore ricerca" che sono comprensibili, specificabili, implementabile, testabile e documentabile.

Limitando corpi dei metodi di essere sempre dentro una struttura o di classe, ci rendono più facile ragionare sul significato di un identificatore qualificato utilizzato in un contesto invocazione; una cosa simile è sempre un membro invocabile del tipo corrente (o un tipo di base).

+2

Si noti che nell'ultimo paragrafo di quell'articolo suggerisco che stiamo considerando la funzionalità per una versione futura, e in effetti, gli scenari di scripting/REPL di Roslyn C# supportano metodi e istruzioni di "livello superiore". –

1

Per me, inserirli nella classe significa raggruppare le funzioni correlate all'interno di una classe. Potresti avere un numero di metodi di estensione nello stesso spazio dei nomi. Se volessi scrivere alcuni metodi di estensione per le classi DirectoryInfo e FileInfo creerei due classi in uno spazio dei nomi IO chiamato DirectoryInfoExtensions e FileInfoExtensions.

È ancora possibile chiamare i metodi di estensione come qualsiasi altro metodo statico. Non so come funziona il compilatore ma forse l'assembly di output se compilato per .net 2 può ancora essere utilizzato da legacy .net framework. Significa anche che la libreria di riflessioni esistente può funzionare e essere utilizzata per eseguire i metodi di estensione senza alcuna modifica. Di nuovo non sono un esperto di compilatori, ma penso che la parola chiave "this" nel contesto di un metodo di estensione sia quella di consentire lo zucchero sintattico che ci permette di usare i metodi come se appartenessero all'oggetto.

0

Possono fare riferimento ad altri membri di classe statici internamente.

Non si dovrebbe considerare solo l'aspetto lato consumatore, ma anche l'aspetto relativo alla manutenzione del codice.

Anche se IntelliSense non distingue rispetto alla classe di appartenenza, le informazioni sono ancora lì attraverso i suggerimenti e qualsiasi produttività strumenti che avete aggiunto al vostro IDE. Questo può essere facilmente utilizzato per fornire un contesto per il metodo in quella che altrimenti sarebbe una lista piatta (e talvolta molto lunga).

Consumatori di consumatori, linea di fondo, non credo che importi molto.

1

.NET Framework richiede che ogni metodo esista in una classe che si trova all'interno di un assieme. Una lingua può consentire che i metodi oi campi vengano dichiarati senza una classe di inclusione specificata esplicitamente, posizionare tutti questi metodi nell'assieme in una classe denominata Fnord_TopLevelDefault e quindi cercare la classe Fnord_TopLevelDefault di tutti gli assembly quando si esegue la ricerca del metodo; la specifica CLS dovrebbe essere estesa per far sì che questa funzionalità funzioni senza intoppi per i progetti in lingue miste. Come con i metodi di estensione, tale comportamento potrebbe essere conforme a CLS se CLS non lo riconoscesse, poiché il codice in una lingua che non utilizzava tale funzione poteva utilizzare un metodo "free-floating" Foo nell'assembly Fnord compitandolo Fnord_TopLevelDefault.Foo , ma sarebbe un po 'brutto.

Una domanda più interessante è la misura in cui consentire ad un metodo di estensione di essere invocato da una classe arbitraria senza richiedere un riferimento chiaramente visibile a tale classe è meno pericoloso di quello che consentirebbe a un metodo statico di non estensione di essere allo stesso modo invocato. Non credo che Math.Sqrt(x) sia davvero più leggibile di Sqrt; anche se non si desidera importare Math ovunque, la possibilità di farlo almeno localmente potrebbe in alcuni casi migliorare notevolmente la leggibilità del codice.

Problemi correlati