2009-04-08 1 views
9

я есть заявлениепечатать имя переменной в C#

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

и я хочу, чтобы написать функцию печати, например, что я передать переменную Int к нему и печатает мне имя переменной и значение.

например, если я называю печати (A) он должен вернуть «A: 10», и печать (B), то он должен вернуть «B: 6»

Короче я хочу знать, как я могу получить доступ к имя переменной и напечатать ее в строке в C#. Я должен использовать отражение?

После прочтения ответов

Привет всем, спасибо за предложения при условии. Я попробую их, однако я хотел бы знать, возможно ли это в .NET 2.0? Ничего похожего на

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

макрос, который есть в C/C++?

ответ

25

Единственный разумный способ сделать это - использовать API Expression; но изменяет код еще дальше ...

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

Примечания: если это для целей отладки, не забудьте добавить [Conditional("DEBUG")] методы, как с помощью переменного таким образом изменяет природу коды в тонком пути.

+0

Ничего себе. Это круто. Отличная работа. –

+0

Привет, Марк, ничего похожего на #define prt (x) std :: cout << #x "= '" << x << "'" << std :: endl; есть ли в C#? –

+0

Каждый день вы узнаете что-то новое. – womp

5

Это невозможно без какой-либо помощи с сайта вызова; даже отражение не знает об именах локальных переменных.

+0

Это возможно в C# 3.0 и лямбда-выражениях. – TcKs

+0

@TcKs: Строго говоря, ему нужен .NET 3.5, а также C# 3.0 –

+0

В вопросе говорится «print (A)» - это невозможно. – Brian

2

Это не возможно сделать с отражением (см. Брайан и Джоэл). В общем, это невозможно, потому что вы не можете гарантировать, что именованное значение передается вашей функции печати. Например, я мог бы так же легко сделать следующее:

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

Ни одно из этих выражений фактически не имеет имени. Что вы ожидаете напечатать здесь?

+0

Не знаю, почему я проголосовал здесь. – JaredPar

+0

Думаю, предполагается, что имя переменной будет передано функции, так как пользователь сам будет использовать эту программу. Хотя ваша линия мышления правильная. Это просто мой POV. –

7

Вы можете использовать лямбда-выражения:

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

Другое решение (от closed post):

Вдохновленный Джон Скита post об обработке Null справочном исключений и вдруг напоминают о проекции есть способ kinda сделать это.

Вот полный рабочий codez:

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

Это делает вопрос полностью выполнимым. Просто добавьте метод prt (object obj), который затем вызывает новый {obj} .GVN(); метод. – mikeschuld

0

Здесь, в будущем мы просто используем оператор nameof.