2009-04-08 9 views
9

j'ai une déclarationnom d'impression de la variable C#

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

et je veux écrire une fonction d'impression de telle sorte que je passe la variable int et il me imprime le nom de la variable et la valeur.

par exemple, si je l'appelle impression (A) il doit retourner « A: 10 », et l'impression (B) il doit retourner « B: 6 »

bref je veux savoir comment puis-je accéder à le nom de la variable et l'imprimer en chaîne dans C#. DOIS-je utiliser la réflexion?

Après avoir lu les réponses

Salut à tous, merci pour les suggestions fournies. Je vais les essayer, mais je voulais savoir si cela est possible dans .NET 2.0? Rien de semblable à

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

macro qui est là en C/C++?

Répondre

25

La seule façon sensée de le faire serait d'utiliser l'API Expression; mais qui change le code encore plus loin ...

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()()); 
} 

Note: si cela est à des fins de débogage, assurez-vous d'ajouter [Conditional("DEBUG")] la méthode, que l'utilisation d'une variable de cette façon change la nature du code subtil façons.

+0

Wow. C'est génial. Bon travail. –

+0

Salut Marc, rien de semblable à #define prt (x) std :: cout << #x "= '" << x << << << << std :: endl; est là en C#? –

+0

Vous apprenez quelque chose de nouveau sur SO tous les jours. – womp

5

Ceci n'est pas possible sans une 'aide' du site d'appel; même la réflexion ne connaît pas les noms des variables locales.

+0

C'est possible dans les expressions C# 3.0 et lambda. – TcKs

+0

@TcKs: Strictement parlant, il faut .NET 3.5 ainsi que C# 3.0 –

+0

La question dit "print (A)" - ce n'est pas possible. – Brian

2

Ceci n'est pas possible avec la réflexion (voir Brian et Joel). En général, cela n'est pas possible simplement parce que vous ne pouvez pas garantir qu'une valeur nommée est transmise à votre fonction d'impression. Par exemple, je pourrais tout aussi bien faire ce qui suit

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

Aucune de ces expressions n'a de nom. Que voulez-vous imprimer ici?

+0

Je ne sais pas pourquoi je suis descendu ici. – JaredPar

+0

Je pense, il est supposé qu'un nom de variable sera passé à la fonction, puisque l'utilisateur lui-même va utiliser le programme. Bien que votre ligne de pensée soit bonne. C'est juste mon point de vue. –

7

Vous pouvez utiliser des expressions 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

Une autre solution (d'un closed post):

Inspiré par Jon Skeet de post au sujet de la gestion des exceptions Null Référence et soudainement rappelé à propos de la projection, il est un moyen de un peu faire ça.

Voici codez de travail complet:

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

Cela rend la question complètement réalisable. Ajoutez simplement une méthode appelée prt (object obj) qui appelle ensuite la nouvelle {obj} .GVN(); méthode. – mikeschuld

0

Ici, dans l'avenir, nous utilisons simplement l'opérateur NomDe.

Questions connexes