Anirudh Goel
Anirudh Goel

Reputation: 4711

print name of the variable in c#

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++?

Upvotes: 13

Views: 30284

Answers (6)

Jack Miller
Jack Miller

Reputation: 7637

If you need to support more types than int, use the Expression API but avoid generics and handle the different expression gracefully:

private static string ToDebugOutput(params Expression<Func<object>>[] variables)
{
    var sb = new StringBuilder();
    foreach (var input in variables)
    {
        string name;
        if (input.Body is UnaryExpression unary && unary.Operand is MemberExpression operand)
        {
            name = operand.Member.Name;
        }
        else if (input.Body is MemberExpression member)
        {
            name = member.Member.Name;
        }
        else
        {
            throw new NotSupportedException($"typeof lambda: {input.Body.GetType()}");
        }

        var result = input.Compile()();
        sb.Append($"{name}={result}, ");
    }

    return sb.ToString();
}

Usage:

string s = "123";
double d = 1.23;
int i2 = 123;
var out2 = ToDebugOutput(() => s, () => d, () => i2);
// out2 = "s=123, d=1.23, i2=123, "

Upvotes: 0

Igor Zevaka
Igor Zevaka

Reputation: 76500

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

Upvotes: 2

Marc Gravell
Marc Gravell

Reputation: 1062492

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.

Upvotes: 28

TcKs
TcKs

Reputation: 26632

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

Upvotes: 7

JaredPar
JaredPar

Reputation: 754505

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?

Upvotes: 2

Brian
Brian

Reputation: 118855

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

Upvotes: 5

Related Questions