Nome del parametro riflettente: abuso delle espressioni lambda C # o brillantezza della sintassi?


428

Sto guardando il componente MvcContrib Grid e sono affascinato, ma allo stesso tempo respinto, da un trucco sintattico usato nella sintassi Grid :

.Attributes(style => "width:100%")

La sintassi sopra imposta l'attributo di stile dell'HTML generato su width:100%. Ora, se presti attenzione, lo "stile" non è specificato da nessuna parte. Viene dedotto dal nome del parametro nell'espressione! Ho dovuto scavare in questo e ho scoperto dove accade la 'magia':

Hash(params Func<object, TValue>[] hash)
{
    foreach (var func in hash)
    {
        Add(func.Method.GetParameters()[0].Name, func(null));
    }
}

Quindi, in effetti, il codice utilizza il tempo formale di compilazione, il nome dei parametri per creare il dizionario delle coppie nome-valore dell'attributo. Il costrutto della sintassi risultante è davvero molto espressivo, ma allo stesso tempo molto pericoloso.

L'uso generale delle espressioni lambda consente la sostituzione dei nomi utilizzati senza effetti collaterali. Vedo un esempio in un libro che dice collection.ForEach(book => Fire.Burn(book))che so di poter scrivere nel mio codice collection.ForEach(log => Fire.Burn(log))e significa la stessa cosa . Ma con la sintassi della griglia MvcContrib qui all'improvviso, trovo codice che cerca attivamente e prende decisioni in base ai nomi che scelgo per le mie variabili!

Quindi è questa pratica comune con la comunità C # 3.5 / 4.0 e gli amanti delle espressioni lambda? O un ladro è un truffatore di cui non dovrei preoccuparmi?


34
Direi che questo sembra ovvio, fintanto che sei disposto a guardare l'intenzione del codice, piuttosto che semplicemente analizzare la sintassi. Che, se stai leggendo un buon codice, è comunque quello che dovresti fare. La sintassi è solo un veicolo per l'intenzione, e direi che questo è un codice che rivela l'intenzione.
Jamie Penney,

191
Ho appena chiesto ad Anders (e al resto del team di progettazione) cosa ne pensassero. Diciamo solo che i risultati non sarebbero stampabili in un giornale per famiglie.
Eric Lippert,

22
In C # al momento manca una sintassi chiara e chiara per le mappe, in particolare le mappe passate alle funzioni. Vari linguaggi dinamici (Ruby, Python, JavaScript, ColdFusion 9) hanno una sintassi chiara e leggera per questo, in un modo o nell'altro.
yfeldblum,

28
Oh, penso che Sembri delizioso. Per quanto riguarda una sintassi per le mappe, sì, sarebbe bello se potessimo fare un nuovo {{"Do", "A deer"}, {"Re", "golden sun"} ...} e fare in modo che il compilatore deduca il costruzione di una mappa, proprio come il nuovo [] {1, 2,3} inizia la costruzione di un array int. Stiamo prendendo in considerazione questo genere di cose.
Eric Lippert,

17
Eric Lippert, ti rispetto molto, ma penso che tu e il gruppo (incluso Anders, che rispetto FREAKIN 'TREMENDOUSLY) lo sbatti troppo duramente. Come ammetti, in C # manca una sintassi ristretta per le mappe e alcuni altri lang (come Ruby) ne hanno di grandi. Questo ragazzo ha trovato il modo di ottenere la sintassi che voleva. Ti concedo che ci sono modi simili per esprimerlo che sono quasi espressivi quanto la sua sintassi con meno svantaggi. Ma la sua sintassi e il fatto che abbia lavorato così duramente per ottenerlo mostra chiaramente la necessità di un miglioramento del linguaggio. Le performance passate indicano che voi ragazzi creerete qualcosa di eccezionale.
Charlie Flowers

Risposte:


147

Ciò ha scarsa interoperabilità. Ad esempio, considera questo esempio C # - F #

C #:

public class Class1
{
    public static void Foo(Func<object, string> f)
    {
        Console.WriteLine(f.Method.GetParameters()[0].Name);
    }
}

F #:

Class1.Foo(fun yadda -> "hello")

Risultato:

Viene stampato "arg" (non "yadda").

Di conseguenza, i progettisti di biblioteche dovrebbero evitare questo tipo di "abusi", o almeno fornire un sovraccarico "standard" (ad es. Che prende il nome della stringa come parametro extra) se vogliono avere una buona interoperabilità tra i linguaggi .Net.


11
Non Questa strategia è semplicemente non portatile. (Nel caso in cui aiuti, ad esempio, F # potrebbe essere in grado di sovraccaricare metodi che differiscono solo per il tipo restituito (l'inferenza del tipo può farlo). Questo può essere espresso nel CLR. Ma F # non lo consente, soprattutto perché se hai fatto questo, quelle API non sarebbero richiamabili da C #.) Quando si tratta di interoperare, ci sono sempre dei compromessi a livello di funzionalità "marginali" per quanto riguarda i vantaggi che ottieni rispetto all'interoperabilità che scambi.
Brian,

32
Non mi piace la non interoperabilità come motivo per non fare qualcosa. Se l'interoperabilità è un requisito, allora farlo, in caso contrario, perché preoccuparsene? Questo è YAGNI IMHO.
John Farrell,

15
@jfar: in .NET CLR l'interoperabilità del terreno ha una dimensione completamente nuova, poiché si suppone che gli assiemi generati in qualsiasi compilatore vengano consumati da qualsiasi altra lingua.
Remus Rusanu,

25
Sono d'accordo che non devi essere conforme a CLS, ma sembra una buona idea se stai scrivendo una libreria o un controllo (e lo snippet che inizia questo è da una griglia, sì?) Altrimenti, stai solo limitando il tuo pubblico / base di clienti
JMarsch,

4
Forse vale la pena cambiare: Func <oggetto, stringa> in Espressione << Func <oggetto, stringa >> E se vincoli il lato destro dell'espressione ad essere solo costanti, puoi avere un'implementazione che lo fa: ID statico pubblico <stringa, stringa> Hash (params Expression <Func <oggetto, stringa >> [] hash) {Dizionario <stringa, stringa> valori = nuovo Dizionario <stringa, stringa> (); foreach (var func in hash) {valori [func.Parameters [0] .Name] = (stringa) ((ConstantExpression) func.Body) .Value; } valori di ritorno; }
davidfowl,

154

Lo trovo strano non tanto per il nome , ma perché la lambda non è necessaria ; potrebbe usare un tipo anonimo ed essere più flessibile:

.Attributes(new { style = "width:100%", @class="foo", blip=123 });

Questo è un modello usato in gran parte di ASP.NET MVC (per esempio) e ha altri usi (un avvertimento , nota anche i pensieri di Ayende se il nome è un valore magico piuttosto che specifico del chiamante)


4
Questo ha anche problemi di interoperabilità; non tutte le lingue supportano la creazione di un tipo anonimo come quello al volo.
Brian,

5
Adoro il modo in cui nessuno ha veramente risposto alla domanda, invece le persone forniscono un argomento "questo è meglio". : p È un abuso o no?
Sam Saffron,

7
Sarei interessato a vedere la reazione di Eric Lippert a questo. Perché è nel codice FRAMEWORK . Ed è altrettanto orribile.
Matt Hinze,

26
Non penso che il problema sia leggibilità dopo che il codice è stato scritto. Penso che il vero problema sia l'apprendimento del codice. Cosa pensi quando dice il tuo intellisense. Attributi (oggetto obj) ? Dovrai andare a leggere la documentazione (cosa che nessuno vuole fare) perché non saprai cosa passare al metodo. Non penso che questo sia davvero migliore dell'esempio nella domanda.
NotDan

2
@Arnis - perché è più flessibile: non si basa sul nome del parametro implicito, che potrebbe (non citarmi) causare problemi con alcune implementazioni lambda (altri linguaggi) - ma puoi anche usare oggetti regolari con proprietà definite. Ad esempio, potresti avere una HtmlAttributesclasse con gli attributi previsti (per intellisense) e semplicemente ignorare quelli con nullvalori ...
Marc Gravell

137

Volevo solo lanciarmi secondo me (sono l'autore del componente griglia MvcContrib).

Questo è sicuramente un abuso di lingua - non c'è che dire. Tuttavia, non lo considererei davvero intuitivo - quando guardi una chiamata Attributes(style => "width:100%", @class => "foo")
penso che sia abbastanza ovvio cosa sta succedendo (Non è certamente peggio dell'approccio di tipo anonimo). Dal punto di vista intellettuale, sono d'accordo che è piuttosto opaco.

Per gli interessati, alcune informazioni di base sul suo utilizzo in MvcContrib ...

Ho aggiunto questo alla griglia come preferenza personale - non mi piace l'uso di tipi anonimi come dizionari (avere un parametro che accetta "oggetto" è opaco quanto uno che accetta parametri Func []) e l'inizializzatore della raccolta Dizionario è piuttosto prolisso (non sono anche un fan delle interfacce fluide verbose, ad esempio dover unire più chiamate a un attributo ("stile", "display: nessuno"). Attributo ("classe", "pippo") ecc.)

Se C # avesse una sintassi meno dettagliata per i letterali del dizionario, non mi sarei preso la briga di includere questa sintassi nel componente griglia :)

Voglio anche sottolineare che l'uso di questo in MvcContrib è completamente facoltativo: si tratta di metodi di estensione che avvolgono sovraccarichi che richiedono invece un IDictionary. Penso che sia importante che se fornisci un metodo come questo, dovresti anche supportare un approccio più "normale", ad esempio per l'interoperabilità con altre lingue.

Inoltre, qualcuno ha menzionato il "sovraccarico di riflessione" e volevo solo sottolineare che in questo approccio non esiste davvero un sovraccarico: non è necessaria alcuna riflessione di runtime o compilazione di espressioni (vedere http://blog.bittercoder.com /PermaLink,guid.206e64d1-29ae-4362-874b-83f5b103727f.aspx ).


1
Ho anche cercato di affrontare alcuni dei problemi sollevati qui in modo più approfondito sul mio blog: jeremyskinner.co.uk/2009/12/02/lambda-abuse-the-mvccontrib-hash
Jeremy Skinner

4
In Intellisense non è meno opaco degli oggetti anonimi.
Brad Wilson,

22
+1 per menzionare che l'interfaccia viene aggiunta tramite metodi di estensione opzionali . Gli utenti non C # (e chiunque sia offeso dall'abuso di lingua) possono semplicemente astenersi dall'utilizzarlo.
Jørn Schou-Rode,

50

preferirei

Attributes.Add(string name, string value);

È molto più esplicito e standard e non si ottiene nulla usando lambda.


20
È vero? html.Attributes.Add("style", "width:100%");non legge bene come style = "width:100%"(l'attuale html generato), mentre style => "width:100%"è molto simile a come appare nel codice HTML risultante.
Jamie Penney,

6
La loro sintassi consente trucchi come .Attributes (id => 'foo', @class => 'bar', style => 'width: 100%'). La firma della funzione utilizza la sintassi params per il numero variabile di args: Attributi (params Func <oggetto, oggetto> [] args). È molto potente, ma mi ci è voluto un po ' di tempo per capire cosa succede.
Remus Rusanu,

27
@Jamie: Cercare di far sembrare il codice C # come il codice HTML sarebbe una cattiva ragione per le descrizioni dei progetti. Sono lingue completamente diverse per scopi completamente diversi e non dovrebbero apparire uguali.
Guffa,

17
Un oggetto anonimo potrebbe anche essere stato usato senza sacrificare la "bellezza"? .Attributes (new {id = "foo", @class = "bar", style = "width: 100%"}) ??
Funka,

10
@Guffa Perché dovrebbe essere una cattiva ragione per le decisioni di progettazione? Perché non dovrebbero apparire uguali? Con questo ragionamento dovrebbero apparire intenzionalmente diversi? Non sto dicendo il tuo torto, sto solo dicendo che potresti voler elaborare più completamente il tuo punto.
Samantha Branham,

45

Benvenuto in Rails Land :)

Non c'è davvero niente di sbagliato fintanto che sai cosa sta succedendo. (È quando questo genere di cose non è ben documentato che c'è un problema).

L'intero framework Rails si basa sull'idea della convenzione sulla configurazione. Denominare le cose in un certo modo ti porta in una convenzione che stanno usando e ottieni molte funzionalità gratuitamente. Seguire la convenzione di denominazione ti porta dove vai più veloce. Il tutto funziona alla perfezione.

Un altro posto in cui ho visto un trucco come questo è nelle asserzioni sulle chiamate di metodo in Moq. Si passa in una lambda, ma la lambda non viene mai eseguita. Usano semplicemente l'espressione per assicurarsi che la chiamata al metodo sia avvenuta e, in caso contrario, generare un'eccezione.


3
Ero un po 'titubante, ma sono d'accordo. A parte il sovraccarico di riflessione, non vi è alcuna differenza significativa tra l'utilizzo di una stringa come in Add () rispetto all'uso di un nome di parametro lambda. Almeno quello che mi viene in mente. Puoi inventarlo e digitare "sytle" senza accorgertene in entrambi i modi.
Samantha Branham,

5
Non riuscivo a capire perché questo non fosse strano per me, e poi mi sono ricordato di Rails. : D
Allyn,

43

Questo è orribile su più di un livello. E no, questo non è niente come Ruby. È un abuso di C # e .NET.

Ci sono stati molti suggerimenti su come farlo in un modo più semplice: tuple, tipi anonimi, un'interfaccia fluida e così via.

Ciò che lo rende così cattivo è che è solo il modo di cercare il proprio bene:

  • Cosa succede quando è necessario chiamare questo da Visual Basic?

    .Attributes(Function(style) "width:100%")

  • È completamente intuitivo e intellisense fornirà poco aiuto per capire come passare le cose.

  • È inutilmente inefficiente.

  • Nessuno avrà idea di come mantenerlo.

  • Qual è il tipo di argomento che va agli attributi? è Func<object,string>? In che modo rivela questa intenzione? Qual è la tua documentazione intellisense che dice "Per favore ignora tutti i valori dell'oggetto"?

Penso che tu sia completamente giustificato avere quei sentimenti di repulsione.


4
Direi: è completamente intuitivo. :)
Arnis Lapsa il

4
Dici che non è niente come Ruby. Ma è un maledetto molto simile alla sintassi di Ruby per specificare le chiavi e i valori di una tabella hash.
Charlie Flowers,

3
Codice che si rompe in conversione alfa! Yey!
Phil

3
@ Charlie, sintatticamente sembra simile, semanticamente è molto diverso.
Sam Saffron,

39

Sono nel campo "Sintassi brillantezza", se lo documentano chiaramente, e sembra così figo, non c'è quasi nessun problema con esso!


10
Amen, fratello. Amen (il 2 ° amen deve rispettare la durata minima per i commenti :)
Charlie Flowers

Il tuo commento da solo è stato molto più del necessario. Ma poi, non puoi semplicemente Amen una volta e poi inserire il tuo commento: D
Sleeper Smith il

37

Entrambi. È abusaggio delle espressioni lambda E brillantezza della sintassi.


16
Quindi è un brillante abuso sintattico delle espressioni lambda? Penso di essere d'accordo :)
Seth Petry-Johnson,

21

Quasi mai mi sono imbattuto in questo tipo di utilizzo. Penso che sia "inappropriato" :)

Questo non è un modo di utilizzo comune, è incompatibile con le convenzioni generali. Questo tipo di sintassi presenta ovviamente vantaggi e svantaggi:

Contro

  • Il codice non è intuitivo (le convenzioni usuali sono diverse)
  • Tende ad essere fragile (la ridenominazione del parametro interromperà la funzionalità).
  • È un po 'più difficile da testare (falsificare l'API richiederà l'uso della riflessione nei test).
  • Se l'espressione viene usata intensamente, sarà più lenta a causa della necessità di analizzare il parametro e non solo il valore (costo di riflessione)

Professionisti

  • È più leggibile dopo che lo sviluppatore si è adattato a questa sintassi.

In conclusione : nella progettazione dell'API pubblica avrei scelto un modo più esplicito.


2
@Elisha - i tuoi pro e contro sono invertiti. Almeno spero che tu non stia dicendo che un Pro abbia un codice "non intuitivo". ;-)
Metro Puffo,

Per questo caso particolare, il nome del parametro lambda e il parametro stringa sono entrambi fragili. È come usare la dinamica per l'analisi xml - è appropriato perché non puoi essere sicuro di xml comunque.
Arnis Lapsa,

19

No, non è certamente una pratica comune. È controintuitivo, non c'è modo di guardare semplicemente il codice per capire cosa fa. Devi sapere come viene utilizzato per capire come viene utilizzato.

Invece di fornire attributi usando una matrice di delegati, i metodi di concatenamento sarebbero più chiari e avrebbero prestazioni migliori:

.Attribute("style", "width:100%;").Attribute("class", "test")

Anche se questo è un po 'più da scrivere, è chiaro e intuitivo.


6
Veramente? Sapevo esattamente cosa intendeva quel frammento di codice quando lo guardavo. Non è così ottuso a meno che tu non sia molto severo. Si potrebbe dare lo stesso argomento sul sovraccarico + per la concatenazione di stringhe e che invece dovremmo sempre usare un metodo Concat ().
Samantha Branham,

4
@Stuart: No, non lo sapevi esattamente, stavi solo indovinando in base ai valori utilizzati. Chiunque può fare questa ipotesi, ma indovinare non è un buon modo di comprendere il codice.
Guffa,

11
Immagino che usare .Attribute("style", "width:100%")mi dia style="width:100%", ma per quello che ne so potrebbe darmi foooooo. Non vedo la differenza.
Samantha Branham,

5
"Indovinare in base ai valori utilizzati" è SEMPRE ciò che fai quando guardi il codice. Se incontri una chiamata a stream.close () supponi che chiuda uno stream, ma potrebbe anche fare qualcosa di completamente diverso.
Wouter Lievens,

1
@Wouter: se indovini SEMPRE durante la lettura del codice, devi avere grosse difficoltà a leggere il codice ... Se vedo una chiamata a un metodo chiamato "close", posso capire che l'autore della classe non è a conoscenza delle convenzioni di denominazione , quindi sarei molto restio a dare tutto per scontato su ciò che fa il metodo.
Guffa,

17

Posso usare questo per coniare una frase?

magic lambda (n): una funzione lambda utilizzata esclusivamente allo scopo di sostituire una stringa magica.


sì ... è divertente. e forse è un po 'magico, nel senso di nessuna sicurezza in fase di compilazione, c'è un posto in cui questo utilizzo causerebbe runtime invece di errori in fase di compilazione?
Maslow,


16

Tutta questa sfuriata sull'orrore è un gruppo di ragazzi di lunga data che reagiscono in modo eccessivo (e io sono un programmatore di lunga data di C # e ancora un grande fan del linguaggio). Non c'è nulla di orribile in questa sintassi. È semplicemente un tentativo di rendere la sintassi più simile a ciò che stai cercando di esprimere. Meno "rumore" c'è nella sintassi di qualcosa, più facile sarà capire dal programmatore. Ridurre il rumore in una riga di codice aiuta solo un po ', ma lascia che si accumuli su un numero sempre maggiore di codice e si rivela un vantaggio sostanziale.

Questo è un tentativo dell'autore di cercare gli stessi benefici che ti offre DSL: quando il codice "assomiglia" a quello che stai cercando di dire, hai raggiunto un posto magico. Puoi discutere se questo è buono per l'interoperabilità o se è abbastanza più bello dei metodi anonimi per giustificare parte del costo della "complessità". Abbastanza giusto ... quindi nel tuo progetto dovresti fare la scelta giusta se usare questo tipo di sintassi. Ma comunque ... questo è un tentativo intelligente da parte di un programmatore di fare ciò che, alla fine della giornata, stiamo tutti cercando di fare (che ce ne rendiamo conto o meno). E quello che stiamo tutti cercando di fare, è questo: "Di 'al computer cosa vogliamo che faccia in un linguaggio il più vicino possibile a come pensiamo a cosa vogliamo che faccia."

Avvicinarsi all'esprimere le nostre istruzioni ai computer nello stesso modo in cui riteniamo internamente una chiave per rendere il software più gestibile e più accurato.

EDIT: avevo detto "la chiave per rendere il software più gestibile e più accurato", che è un po 'follemente esagerato di unicorno. L'ho cambiato in "una chiave".


12

Questo è uno dei vantaggi degli alberi delle espressioni: è possibile esaminare il codice stesso per ulteriori informazioni. Ecco come .Where(e => e.Name == "Jamie")può essere convertito nella clausola SQL Where equivalente. Questo è un uso intelligente degli alberi delle espressioni, anche se spero che non vada oltre. Qualcosa di più complesso sarà probabilmente più difficile del codice che spera di sostituire, quindi sospetto che si autolimiterà.


È un punto valido, ma la verità nella pubblicità: LINQ viene fornito con un intero set di attributi come TableAttribute e ColumnAttribute che rendono questo un affare più legittimo. Anche la mappatura linq esamina i nomi delle classi e delle proprietà, che sono probabilmente più stabili dei nomi di un parametro.
Remus Rusanu,

Sono d'accordo con te lì. Ho cambiato leggermente la mia posizione in merito dopo aver letto ciò che Eric Lippert / Anders Helsberg / ecc. Avevano da dire sull'argomento. Ho pensato di lasciare questa risposta perché è ancora in qualche modo utile. Per quello che vale, ora penso che questo stile di lavoro con HTML sia bello, ma non si adatta al linguaggio.
Jamie Penney,

7

È un approccio interessante. Se hai costretto il lato destro dell'espressione a essere solo costanti, allora puoi implementare usando

Expression<Func<object, string>>

Che penso sia quello che vuoi davvero invece del delegato (stai usando lambda per ottenere nomi di entrambe le parti) Vedi l'implementazione ingenua di seguito:

public static IDictionary<string, string> Hash(params Expression<Func<object, string>>[] hash) {
    Dictionary<string, string> values = new Dictionary<string,string>();
    foreach (var func in hash) {
        values[func.Parameters[0].Name] = ((ConstantExpression)func.Body).Value.ToString();
    }
    return values;
}

Ciò potrebbe anche risolvere il problema dell'interoperabilità linguistica menzionato in precedenza nel thread.


6

Il codice è molto intelligente, ma potenzialmente causa più problemi che risolve.

Come hai sottolineato, ora c'è un'oscura dipendenza tra il nome del parametro (stile) e un attributo HTML. Non viene eseguito alcun controllo del tempo di compilazione. Se il nome del parametro è errato, la pagina probabilmente non avrà un messaggio di errore di runtime, ma sarà molto più difficile trovare un bug logico (nessun errore, ma comportamento errato).

Una soluzione migliore sarebbe quella di avere un membro di dati che può essere verificato in fase di compilazione. Quindi invece di questo:

.Attributes(style => "width:100%");

il codice con una proprietà Style può essere verificato dal compilatore:

.Attributes.Style = "width:100%";

o anche:

.Attributes.Style.Width.Percent = 100;

Questo è più lavoro per gli autori del codice, ma questo approccio sfrutta la forte capacità di controllo del tipo di C #, che aiuta a prevenire che i bug entrino nel codice in primo luogo.


3
Apprezzo il controllo del tempo di compilazione, ma penso che ciò dipenda da una questione di opinioni. Forse qualcosa come i nuovi Attributi () {Stile: "larghezza: 100%"} avrebbe conquistato più persone, dato che è più conciso. Tuttavia, l'implementazione di tutto ciò che l'HTML consente è un lavoro enorme e non posso incolpare qualcuno per aver usato solo stringhe / lambdas / classi anonime.
Samantha Branham,

5

anzi sembra Ruby =), almeno per me l'uso di una risorsa statica per una "ricerca" dinamica successiva non si adatta alle considerazioni di progettazione API, spero che questo trucco intelligente sia facoltativo in quell'API.

Potremmo ereditare da IDictionary (o meno) e fornire un indicizzatore che si comporta come un array php quando non è necessario aggiungere una chiave per impostare un valore. Sarà un uso valido della semantica .net non solo di c #, e avrà ancora bisogno di documentazione.

spero che sia di aiuto


4

Secondo me è un abuso degli lambda.

Per quanto riguarda la brillantezza della sintassi, trovo style=>"width:100%"chiaramente confuso. Soprattutto a causa del =>invece di=


4

IMHO, è un bel modo di farlo. Tutti amiamo il fatto che nominare un controller di classe lo renderà un controller in MVC giusto? Quindi ci sono casi in cui la denominazione è importante.

Anche l'intenzione è molto chiara qui. È molto facile capire che .Attribute( book => "something")si tradurrà in book="something"e .Attribute( log => "something")comporteràlog="something"

Immagino che non dovrebbe essere un problema se lo tratti come una convenzione. Sono dell'opinione che qualunque cosa ti faccia scrivere meno codice e rendere evidente l'intenzione è una buona cosa.


4
Denominare un controller di classe non farà squat se però non erediti dal controller ...
Jordan Wallwork,

3

Se i nomi dei metodi (func) sono ben scelti, questo è un modo geniale per evitare mal di testa da manutenzione (ad esempio: aggiungere una nuova funzione, ma si è dimenticato di aggiungerla all'elenco di mappatura dei parametri di funzione). Certo, devi documentarlo pesantemente e faresti meglio a generare automaticamente la documentazione per i parametri dalla documentazione per le funzioni in quella classe ...


1

Penso che questo non sia meglio di "stringhe magiche". Non sono un grande fan dei tipi anonimi neanche per questo. Ha bisogno di un approccio migliore e fortemente tipizzato.

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.