Perché i metodi di estensione non vengono utilizzati in modo più esteso in .NET BCL?

6

Ho trovato il concetto di "metodo di estensione" di C # semplicemente meraviglioso. Ci consente di fare cose come:

E la cosa più bella a riguardo IMHO è che l'aggiunta di un metodo non rompe la compatibilità con le versioni precedenti .

Tuttavia, ho trovato quasi nessun metodo di estensione in .NET BCL. Ed è molto comune che, vedo un metodo statico e metodi di estensione in mente.

Quando è stato progettato il BCL, i metodi di estensione non erano presenti. Ma perché non vengono convertiti in metodi di estensione ora? Specialmente quando rompe la retrocompatibilità? Qualsiasi motivo?

    
posta Gulshan 19.05.2011 - 08:50
fonte

2 risposte

10

Il punto dei metodi di estensione è per consentire di aggiungere funzionalità a classi che non puoi modificare o ereditare da . Ad esempio, se in un caso specifico si desidera visualizzare un numero intero come un denaro,

  • o crei una classe statica HelloWorld con il metodo public static string DisplayIntAsMoney(int amount) e usala come HelloWorld.DisplayIntAsMoney(5990) per ottenere "$ US 59.90",
  • oppure crei un metodo di estensione e utilizzalo come 5990.AsMoney() .

Il primo è brutto. Anche la seconda è brutta, ma molto più corta.

Ma i metodi di estensione non devono essere usati ovunque per fare tutto. Questo è uno strumento. Non usarlo abusivamente.

Ad esempio, se hai scritto una libreria con una classe e vuoi aggiungervi delle funzioni da utilizzare in un altro progetto, hai due possibilità:

  • Utilizza un metodo di estensione,

  • Torna alla precedente libreria e modificala fornendo una classe ereditata che fornisce la funzione o aggiungendo la funzione direttamente alla classe.

Il primo è brutto. Molto brutto. Ti costringe anche a violare il principio DRY , poiché probabilmente riscrivi lo stesso metodo di estensione più e più volte in molti progetti che utilizzeranno la stessa libreria. Il secondo invece ti consente di fornire più funzionalità senza compromettere la compatibilità con le versioni precedenti (almeno nel caso in cui crei una classe ereditata).

Detto questo, i metodi di estensione sono piuttosto utili in due casi:

  • Quando devi estendere le classi non puoi modificarle,

  • Quando devi fornire funzionalità comuni senza dover modificare l'enorme base di codice esistente o devi fornire funzionalità che possono essere attivate e disattivate aggiungendo o rimuovendo riferimenti al tuo progetto.

La prima ragione non si applica a .NET BCL. Microsoft ha il codice sorgente. Microsoft può modificarlo direttamente, invece di usare i metodi di estensione. È esattamente quello che succede in realtà.

La seconda ragione si applica alla base di codice .NET. Ma, aspetta, non stanno facendo esattamente questa cosa con LINQ, Reactive Extensions, ecc.?

Modifica in seguito al tuo commento:

Ci sono quattro motivi per cui abbiamo Math.Round(a) invece di a.Round() :

  • Math.Round esisteva prima che comparissero i metodi di estensione, e non è mai una buona idea riscrivere un'API esistente solo per il gusto di riscrivere, infrangendo tutto il codice sorgente precedente.

  • Avere metodi di estensione per Round o Pow ma metodi statici per Max è troppo confuso, specialmente quando non si utilizza l'API troppo spesso. In realtà, so che se voglio qualcosa di matematico, devo digitare Ma , completamento automatico e iniziare a digitare il nome del metodo. Con il tuo approccio, a volte mi sbaglio iniziando a digitare Ma , cercando il metodo, scoprendo che il metodo non esiste, ricordando che potrebbe essere un metodo di estensione, rimuovendo Math. e iniziando a digitare in un modo ottenere il completamento automatico per il metodo di estensione.

  • Math metodi appartengono a System namespace. Questo spazio dei nomi è dichiarato in quasi tutti i file di ogni progetto. Ciò significa che avrai il completamento automatico di Round , Floor ecc. Ogni volta che inserisci un numero intero seguito da un punto. È troppo fastidioso. Avere troppi metodi in intellisense non solo rende difficile trovare quella buona, ma diminuisce anche le prestazioni nei computer lenti.

  • float , double e int non ereditano dallo stesso tipo. Se i metodi di estensione LINQ sono comunemente associati a IEnumerable o ad alcuni tipi di base, è impossibile farlo con i metodi Math . L'unico modo è scrivere codice per ogni tipo, che probabilmente non è l'approccio più elegante. Con metodi statici, ci sono anche sovraccarichi, ma sono molto più brevi da scrivere e più facili da capire.

risposta data 19.05.2011 - 10:05
fonte
3

La mia ipotesi è che il team CLR abbia più pesci da friggere, quindi tornare indietro e ripetere le vecchie progettazioni. Sfortunatamente una volta che qualcosa entra nel framework .Net è lì per sempre. Se potessero tornare indietro, scommetto che ci sono un sacco di cose che farebbero diverse tra cui l'uso di parametri out / ref, l'uso di alcune interfacce e la masterizzazione di un gruppo di classi base (MarshalByRef chiunque):)

L'aggiunta di metodi estensioni per tutto renderebbe il quadro un po 'più disordinato. Come dici tu puoi facilmente aggiungere metodi di estensione per te stesso, basta fare riferimento ai vecchi metodi statici

    
risposta data 19.05.2011 - 09:36
fonte

Leggi altre domande sui tag