2009-04-08 40 views
9

i hai dichiarazioninome di stampa della variabile in C#

int A = 10,B=6,C=5; 

e voglio scrivere una funzione di stampa in modo tale che mi passa la variabile int ad esso e mi stampa il nome della variabile e il valore.

ad esempio se io chiamo di stampa (A) deve restituire "A: 10", e la stampa (B) allora deve tornare "B: 6"

insomma voglio sapere come posso accedere il nome della variabile e stampalo in stringa in C#. Devo usare la riflessione?

Dopo aver letto le risposte

Ciao a tutti, grazie per i suggerimenti forniti. Li proverò, tuttavia volevo sapere se è possibile in .NET 2.0? Niente di simile a

#define prt(x) std::cout << #x " = '" << x << "'" << std::endl; 

macro che c'è in C/C++?

risposta

25

L'unico modo ragionevole per farlo sarebbe quello di utilizzare l'API Expression; ma che cambia il codice ulteriormente ...

static void Main() { 
    int A = 10, B = 6, C = 5; 
    Print(() => A); 
} 
static void Print<T>(Expression<Func<T>> expression) { 
    Console.WriteLine("{0}={1}", 
     ((MemberExpression)expression.Body).Member.Name, 
     expression.Compile()()); 
} 

Nota: se questo è per scopi di debug, assicurarsi di aggiungere [Conditional("DEBUG")] al metodo, come l'utilizzo di una variabile in questo modo cambia la natura del codice in sottili modi.

+0

Wow. Questo e spettacolare. Buon lavoro. –

+0

Ciao Marc, niente di simile a #define prt (x) std :: cout << #x "= '" << x << "'" << std :: endl; c'è in C#? –

+0

Ogni giorno impari qualcosa di nuovo su SO. – womp

5

Questo non è possibile senza alcun 'aiuto' dal sito di chiamata; anche la riflessione non conosce i nomi delle variabili locali.

+0

È possibile in C# 3.0 e espressioni lambda. – TcKs

+0

@TCK: Strettamente parlando, richiede .NET 3.5 e C# 3.0 –

+0

La domanda dice "stampa (A)" - non è possibile. – Brian

2

Questo non è possibile fare con la riflessione (vedere Brian e Joel). In generale ciò non è possibile semplicemente perché non è possibile garantire che un valore con nome venga passato alla funzione di stampa. Per esempio, potrei fare altrettanto facilmente quanto segue

print(42); 
print(A + 42); 

Nessuna di queste espressioni ha effettivamente un nome. Cosa ti aspetti di stampare qui?

+0

Non so perché ho votato qui. – JaredPar

+0

Penso, si presume che un nome di variabile verrà passato alla funzione, poiché l'utente stesso utilizzerà il programma. Anche se la tua linea di pensiero è giusta. È solo il mio punto di vista. –

7

È possibile utilizzare le espressioni lambda:

static void Main(string[] args) { 
    int A = 50, B = 30, C = 17; 
    Print(() => A); 
    Print(() => B); 
    Print(() => C); 
} 

static void Print<T>(System.Linq.Expressions.Expression<Func<T>> input) { 
    System.Linq.Expressions.LambdaExpression lambda = (System.Linq.Expressions.LambdaExpression)input; 
    System.Linq.Expressions.MemberExpression member = (System.Linq.Expressions.MemberExpression)lambda.Body; 

    var result = input.Compile()(); 
    Console.WriteLine("{0}: {1}", member.Member.Name, result); 
} 
2

Un'altra soluzione (da un closed post):

Ispirato da Jon Skeet di post su Null Riferimento gestione delle eccezioni e improvvisamente di essere ricordata la proiezione c'è un modo per fare così.

Ecco completa codez di lavoro:

public static class ObjectExtensions { 
    public static string GetVariableName<T>(this T obj) { 
     System.Reflection.PropertyInfo[] objGetTypeGetProperties = obj.GetType().GetProperties(); 

     if(objGetTypeGetProperties.Length == 1) 
      return objGetTypeGetProperties[0].Name; 
     else 
      throw new ArgumentException("object must contain one property"); 
    } 
} 

class Program { 
    static void Main(string[] args) { 
     string strName = "sdsd"; 
     Console.WriteLine(new {strName}.GetVariableName()); 

     int intName = 2343; 
     Console.WriteLine(new { intName }.GetVariableName()); 
    } 
} 
+0

Questo rende la domanda completamente fattibile. Basta aggiungere un metodo chiamato prt (object obj) che chiama il nuovo {obj} .GVN(); metodo. – mikeschuld

0

qui in futuro usiamo l'operatore nameof.

Problemi correlati