2

Edit: For clarifing my problem clearly, I asked a new question.


Edit: Because the reflection solution is impossible, so I changed the title from "Is there any way to get the variable name in C#?" to "How to distinguish class members with same attribute using reflection in C#"


Edit: The variable name is not an accurate meaning, my goal is

  • Getting the variable name using reflection if possible(someone already told me that's impossible).
  • Use a solution to get the information added when declaring the member in any circumstance, for example, in the CheckMethod.

I thought I could use Reflection to get the variable info, including its name, but is doesn't work.

public class C
{
    public List<string> M1{get; set;}
    public List<string> M2{get; set;}
}

static void Main(string[] args)
{
    C c = new C();
    CheckMethod(c.M1);
    ChekcMethod(c.M2);
}

void CheckMethod(List<string> m)
{
    //Want to get the name "M1" or "M2", but don't know how
    Console.Write(m.VariableName);
}

Then, I thought attribute could be the solution.

public class C
{
    [DisplayName("M1")]
    public List<string> M1{get; set;}
    [DisplayName("M2")]
    public List<string> M2{get; set;}
}

static void Main(string[] args)
{
    C c = new C();
    CheckMethod(c.M1);
    ChekcMethod(c.M2);
}

void CheckMethod(List<string> m)
{
    //Find all properties with DisplayNameAttribute
    var propertyInfos = typeof(C)
            .GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance
                           | BindingFlags.GetField | BindingFlags.GetProperty)
            .FindAll(pi => pi.IsDefined(typeof(DisplayNameAttribute), true));
    foreach (var propertyInfo in propertyInfos)
    {
        //I can get the DisplayName of all properties, but don't know m is M1 or M2

    }
}
  • Is there any native reflection way to get variable's name?It's impossible
  • How to determine which member variable the method parameter represent?

I'm working with Unity3D, so the .net version is 3.5

Community
  • 1
  • 1
Matrix Bai
  • 1,097
  • 3
  • 11
  • 20
  • 1
    You're mixing things up, variable/method/property. I think you want to read the Attributes of properties with reflection. You might have a look here: _Accessing Attributes by Using Reflection (C#)_ https://msdn.microsoft.com/en-us/library/mt653983.aspx – Jeroen van Langen Aug 05 '16 at 08:45
  • This question will only have answers along the lines of "No, you can't do that but here's what you can do instead". The value passed to `CheckMethod` is a `List`, this value has no knowledge of where it came from. – Lasse V. Karlsen Aug 05 '16 at 09:19
  • You can easily obtain the name of a property using reflection but you cannot do that with only the value of the property available. To find the property you must know the name of the property (or something other that identifies it) in which case you've just wrapped this in a chicken-and-egg problem. If you absolutely must know the name of the source of the value passed to a method, either 1. build the name of it into the value passed into the method (give it a .Name property) or 2. pass the name alongside the value (extra parameter) – Lasse V. Karlsen Aug 05 '16 at 09:22
  • In addition to @LasseV.Karlsen _" this value has no knowledge of where it came from"_ It's just another reference to an instance of `List` and there is no connection between them unless you could enumerate all references to one single instance. – Jeroen van Langen Aug 05 '16 at 09:22
  • Thanks for @LasseV.Karlsen 's explanation. DisplayNameAttribute is my alternative solution, and I can get the information I want but don't know which is which. – Matrix Bai Aug 05 '16 at 09:25
  • What do you want to achieve? Looks like an X-Y-Problem to me: you don't know how to do X, then came up with Y, and now you got stuck somewhere in Y and ask for help with Y. Tell us X. – Bernhard Hiller Aug 05 '16 at 10:02
  • X is getting the variable member name in .net3.5 and which is impossible. – Matrix Bai Aug 05 '16 at 10:08

2 Answers2

3

Using reflection, it is not possible. After the compilation variable names won't exist, so you can't use reflection at run time to get the name. There are some other methods like expression trees and closures. If you can use them try this.

static string GetVariableName<T>(Expression<Func<T>> expr)
{
    var body = (MemberExpression)expr.Body;

    return body.Member.Name;
}

To use this kind of functions you can do

GetVariableName(() => someVar)

And if you are using C# 6 a new nameof keyworkd has been added. More info

https://msdn.microsoft.com/en-us/magazine/dn802602.aspx

Rish
  • 1,303
  • 9
  • 22
acostela
  • 2,597
  • 3
  • 33
  • 50
  • I tried this before, but it's not satisfied my need. It returns the variable name which input in the call, I want some kind of original name when declaring this member variable, that's why I used the attribute solution. – Matrix Bai Aug 05 '16 at 08:55
  • As somebody tell you before I think that you are mixing some concepts. If you want the variable name you should use what I wrote in my answer. – acostela Aug 05 '16 at 08:57
  • I did try your method before and it's not what I want. My goal is getting the "M1" or "M2" names in the CheckMethod, the parameter name can be any, for example, "any", using your method in the CheckMethod only get the name "any", not "M1" or "M2". – Matrix Bai Aug 05 '16 at 09:11
  • But you can't get what you want. There is no way to get hold of what the variable was named in the C# code since that information is not compiled into the assembly. It is present in the debug information but I don't think there's any API to access that. – Lasse V. Karlsen Aug 05 '16 at 09:14
  • You can get hold of the names of properties, but a method that has been called has no way of knowing where its arguments came from, whether they were from constant literals, local variables in the calling method, properties, fields, or simply calculated expressions. You don't have this information. You will have to think of an alternative. – Lasse V. Karlsen Aug 05 '16 at 09:16
  • @LasseV.Karlsen thank you for clarifying in comments :) – acostela Aug 05 '16 at 09:19
0

You could use nameof(anyVariable) which should return the name of any variable as a string.

Ian H.
  • 3,840
  • 4
  • 30
  • 60