views:

1299

answers:

5

i have a statement

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

and i want to write a print function such that i pass the int variable to it and it prints me the variable name and the value.

eg if i call print(A) it must return "A: 10", and print (B) then it must return "B:6"

in short i want to know how can i access the name of the variable and print it to string in c#. DO i have to use reflection?

After reading the answers

Hi all, thanks for the suggestions provided. I shall try them out, however i wanted to know if it is at all possible in .NET 2.0? Nothing similar to

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

macro which is there in C/C++?

+5  A: 

This is not possible without some 'help' from the call site; even reflection does not know about names of local variables.

Brian
It's posible in C# 3.0 and lambda expressions.
TcKs
@TcKs: Strictly speaking, it needs .NET 3.5 as well as C# 3.0
Marc Gravell
The question says "print(A)" - it's not possible.
Brian
+14  A: 

The only sensible way to do this would be to use the Expression API; but that changes the code yet further...

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: if this is for debugging purposes, be sure to add [Conditional("DEBUG")] to the method, as using a variable in this way changes the nature of the code in subtle ways.

Marc Gravell
Wow. This is awesome. Good job.
Brian Genisio
Hi Marc, nothing similar to #define prt(x) std::cout << #x " = '" << x << "'" << std::endl;is there in C#?
Anirudh Goel
You learn something new on SO every day.
womp
+2  A: 

This is not possible to do with reflection (see Brian and Joel). In general this is not possible simply because you cannot guarantee a named value is being passed to your print function. For instance, I could just as easily do the following

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

Neither of these expressions actually has a name. What would you expect to print here?

JaredPar
Not sure why I got down voted here.
JaredPar
I think, it is assumed that a variable name will be passed to the function, since the user himself is going to use the program. Though your line of thinking is right. It's just my POV.
Anirudh Goel
+4  A: 

You can use lambda expressions:

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 );
}
TcKs
+2  A: 

Another solution (from a closed post):

Inspired by Jon Skeet's post about Null Reference exception handling and suddenly being reminded about projection there is a way to kinda do that.

Here is complete working 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());
    }
}
Igor Zevaka
This makes the question completely doable. Just add a method called prt(object obj) that then calls the new {obj}.GVN(); method.
mikeschuld