2012-02-17 12 views
18

Scrivo spesso codice C# che deve utilizzare stringhe magiche per esprimere i nomi di proprietà. Tutti conoscono i problemi con le stringhe magiche. Sono molto difficili da refactoring, non hanno il controllo del tempo di compilazione e spesso portano a problemi difficili da diagnosticare. Tuttavia C# /. NET li usa dappertutto sul posto per rappresentare i nomi di proprietà/classe/metodo.Riflessione del tempo di compilazione in C#

Questo problema persiste da anni e anni e l'unica soluzione valida al momento consiste nell'utilizzare un albero di espressioni che viene quindi analizzato in fase di esecuzione per il nome della proprietà. Ciò consente di ottenere un controllo soddisfacente in fase di compilazione, ma complica il codice (richiedendo parametri di tipo Expression), e comporta un costo di runtime.

Qualcuno sa se è mai esistita una considerazione per C# /. NET per aggiungere una riflessione in fase di compilazione per superare questo problema pervasivo?

Sembra che sarebbe un'aggiunta facile da fare, sarebbe un cambiamento senza interruzione e sarebbe di grande beneficio per molti sviluppatori. L'operatore typeof() esegue già una forma di riflessione in fase di compilazione, quindi sembra che un operatore nameof() (o qualcosa di simile) sia molto gratuito.

Inoltre, qualcuno sa di potenziali problemi con tale funzione?

Grazie per l'aiuto.

+0

possibile duplicato di [Utilizzo di un'espressione lambda per evitare l'utilizzo di una "stringa magica" per specificare una proprietà] (http://stackoverflow.com/questions/3330758/using-a-lambda-expression-to-avoid-using -a-magic-string-to-specific-a-property) –

+1

Vedi anche: [Ottieni la proprietà, come stringa, da un'espressione >] (http://stackoverflow.com/questions/2789504/get-the-property-as-a-string-from-an-expressionfunctmodel-tproperty) –

+3

@KirkWoll Questo non è un duplicato di quella domanda. Il secondo paragrafo della domanda indica che MgSam ha familiarità con la tecnica dell'albero dell'espressione; la domanda è se ci potrebbe essere una nuova funzionalità nei lavori che consentirebbe una nuova soluzione al problema. – phoog

risposta

11

Straight from the source - questo è un post di un blog di un designer di linguaggio C# e l'utente in questo post chiede le stesse domande e risposte. L'autore dice che sarebbe necessario specificare una sintassi per ogni elemento di metadati che si vorrebbe richiedere e non è banale, ad es. quale sovraccarico vuoi, se vuoi il metodo "info-of" e il metodo è sovraccarico? Cosa succede se ci sono generici e implementazioni esplicite dell'interfaccia coinvolti? E così via. Si scopre che, sebbene non sia stata ritenuta meritevole di implementazione nel 2009 per queste ragioni, la otterremo nel C# 6 nel 2015 - vedi C# Language Design Notes for Jul 9, 2014.

+1

Beh, è ​​un post sul blog di un designer di linguaggio C# su problemi reali con l'implementazione di un "infoof () "Operatore che funziona come typeof ma per qualsiasi metadata (metodo, proprietà ecc.). OP fa le stesse domande di "Utente" dall'articolo e "Utente" ottiene tutte le risposte. – cynic

+2

La risposta di Eric sembra implicare che l'uso di Expressions ha risolto il problema. Ma molte delle tecnologie Microsoft utilizzano stringhe magiche per rappresentare classi/proprietà: ASP .NET (Web Forms e MVC), Silverlight, WPF, Winforms; li usano tutti. Per non parlare degli sviluppatori di terze parti di cui puoi contare sulle librerie. E se guardi abbastanza, troverai anche le librerie di base che le usano. Per me questo sembra un problema più pervasivo (e più facile da affrontare) rispetto al problema risolto dalle parole chiave asincrone/attese. – MgSam

+1

Non credo che il post risponda al perché non per le proprietà che non possono essere sovraccaricate. – ja72

0

Tuttavia C# /. NET li utilizza dappertutto per rappresentare i nomi di proprietà/classe/metodo.

Prima di tutto: non sono d'accordo. Esistono alcuni framework (WebForms, ad esempio) che utilizzano stringhe magiche dappertutto, ma le librerie di base per C# e .NET tendono ad evitare cose del genere in modo notevole.

In secondo luogo: in molti casi in cui vengono utilizzate stringhe magiche, ReSharper è in grado di riconoscere gli errori. Questo può aiutare un bel po '.

Infine: ciò che stai chiedendo potrebbe essere possibile tramite il compilatore Roslyn, che promette di fornire "Compilazione come servizio".

+1

Concordo sul fatto che le librerie di base .NET rimangano lontane dalle stringhe magiche, ma se hai guardato MVC3 a tutti, oh uomo, il suo inferno MagicString :) Grazie a Dio per la capacità di ReSharper di dirti se hai digitato un controller o un'azione sbagliata nome in un parametro stringa! – CodingWithSpike

+1

Il compilatore conosce già tutte le informazioni rilevanti durante la compilazione per rendere possibile questa funzione. Da quanto ho capito, Roslyn consentirà semplicemente a terze parti di ottenere più facilmente intuizioni simili nel codice prima della compilazione. – MgSam

+1

@MgSam: Roslyn sembra consentire la configurazione di regole di compilazione personalizzate, quindi è possibile prevedere la possibilità di scrivere un albero di espressioni nel codice che viene convertito in un nome di metodo, nome controller, ecc. In fase di compilazione. – StriplingWarrior

6

Stavo avendo un problema simile. Solo di recente è stato scoperto che .NET Framework 4.5 ha una funzione chiamata attributi Caller Info. Usando questi, è possibile ottenere informazioni sul chiamante su un metodo in fase di compilazione. È possibile ottenere il percorso del file del codice sorgente, il numero di riga nel codice sorgente e il nome del membro del chiamante.

public void DoProcessing() 
{ 
    TraceMessage("Something happened."); 
} 

public void TraceMessage(string message, 
     [CallerMemberName] string memberName = "", 
     [CallerFilePath] string sourceFilePath = "", 
     [CallerLineNumber] int sourceLineNumber = 0) 
{ 
    Trace.WriteLine("message: " + message); 
    Trace.WriteLine("member name: " + memberName); 
    Trace.WriteLine("source file path: " + sourceFilePath); 
    Trace.WriteLine("source line number: " + sourceLineNumber); 
} 
7

In C# 6.0, un nuovo operatore, nameof, è stato aggiunto che vi permetterà di ottenere i nomi di proprietà, classi, i campi, gli eventi e le variabili al momento della compilazione.

Link to the design notes

Non più di riflessione per informazioni il compilatore sa già in fase di progettazione!