16

Maybe, this question is stupid, but in my specific situation i want to get instance name, so what i mean :

class Student
{
     private string name {get; private set;}

     public Student(string name) 
     {
         this.name = name 
     }

     public getInstanceName() 
     {
        //some function
     }

}

so when i make an student

   Student myStudent = new Student("John");

it's stupid but i want this

 myStudent.getInstanceName(); // it should return 'myStudent'
6
  • 1
    So you want the name of the variable? Commented May 3, 2013 at 16:39
  • 3
    What do you want that for? it makes no sense. Commented May 3, 2013 at 16:39
  • Do you want the name of the variable e..g myStudent, or the name of the student e.g. John? Commented May 3, 2013 at 16:40
  • If your doing this for your own classes then just make your own property and constructor that returns the string. Won't be of any use though and error prone Commented May 3, 2013 at 16:42
  • 3
    It makes total sense to me. I wanted this to imitate objecive-C's NSDictionaryOfVariableBindings in Xamarin but I can´t because there´s no way to get the instance name... Commented Feb 6, 2014 at 10:36

8 Answers 8

20

This is now possible in C# 6.0:

Student myStudent = new Student("John");
var name = nameof(myStudent); // Returns "myStudent"

This is useful for Code Contracts and error logging as it means that if you use "myStudent" in your error message and later decide to rename "myStudent", you will be forced by the compiler to change the name in the message as well rather than possibly forgetting it.

Sign up to request clarification or add additional context in comments.

1 Comment

FYI C# 6.0 != .net 4.6, so This is now possible with C# 6.0. The version of C# you are using is based on the compiler support => IDE. To write in C# 6.0 you need Visual Studio 2015.
10

This is not possible in C#. At runtime, the variable names will not even exist, as the JIT removes the symbol information.

In addition, the variable is a reference to the class instance - multiple variables can reference the same instance, and an instance can be referenced by variables of differing names throughout its lifetime.

Comments

5

Give this a try

string result = Check(() => myStudent);

static string Check<T>(Expression<Func<T>> expr)
{
    var body = ((MemberExpression)expr.Body);
    return body.Member.Name;
}

Or

GetName(new { myStudent });

static string GetName<T>(T item) where T : class 
{
  return typeof(T).GetProperties()[0].Name;
}

1 Comment

+1 from me - This is an interesting approach. Note that it's not actually getting the variable name, as much as making a new type with a variable to match it in a field or property, and fetching that. Works in most cases (you can break this, but in general, an interesting approach).
5

This question is very old, but the answer changed with the release of .Net Framework 4.6. There is now a nameof(..) operator which can be used to get the string value of the name of variables at compile time.

So for the original question C# nameof(myStudent) // returns "myStudent"

Comments

1

Variable names exist only for your benefit while coding. Once the the code is compiled, the name myStudent no longer exists. You can track instance names in a Dictionary, like this:

var students = new Dictionary<string, Student>();
var students["myStudent"] = new Student("John");

// Find key of first student named John
var key = students.First(x => x.Value.Name == "John").Key; // "myStudent"

Comments

1

No, but you could do this

var myStudent = new Student("John").Named("myStudent");
var nameOfInstance = myStudent.Name();

public static class ObjectExtensions
{
    private static Dictionary<object,string> namedInstances = new Dictionary<object, string>(); 

    public static T Named<T>(this T obj, string named)
    {
        if (namedInstances.ContainsKey(obj)) namedInstances[obj] = named;
        else namedInstances.Add(obj, named);
        return obj;
    }

    public static string Name<T>(this T obj)
    {
        if (namedInstances.ContainsKey(obj)) return namedInstances[obj];
        return obj.GetType().Name;
    }
}

Comments

1

So I've been searching around for about a week trying to figure out how to do this. While gathering bits and pieces of stuff I didn't know I found a relatively simple solution.

I think the original poster was looking for something like this, because if you have to use the name of the class to find out the name of the class then what's the point..

For those saying "It's not possible" and "Why would you want to.." my particular reason is for a class library where I have a class that the app developer can call the instances whatever they want, and it's meant to have multiple instances with different names. So I needed a way to be able to identify those instances so I can use the right one for the circumstance.

    public static List<Packet> Packets = new List<Packet>();
    public class Packet
    {
        public Packet(string Name)
        {
            Packets.Add(this);
            name = Name;
        }
        internal string _name;
        public string name
        {
            get { return _name; }
            set { _name = value; }
        }
    }

It does require that they pass in the name of the instance as I've not yet figured out how to acquire the name they're using from inside the constructor. That is likely the thing that isn't possible.

    public Packet MyPacket = new Packet("MyPacket");

This creates the instance, stores a reference to it in Packets and saves it's name in the newly created instance.

To get the name associated with the Packet and connect it to a variable..

    Packet NewName = Packets[Packets.FindIndex(x => x.name == "MyPacket");

Whether you use the same variable name or a new one doesn't really matter, it's just linking the instance you want to it.

    Console.WriteLine(NewName.name); // Prints MyPacket

For instances with the same name you would have to come up with some other way to tell them apart, which would require another list and some logic to determine which one you want.

Comments

-2

No, this is not possible, because it's totally ridiculous. An object can never, in any way, know the name of the variable you happen to assign it to. Imagine:

Student myStudent = new Student("John");
Student anotherStudent = myStudent;
Console.Write(anotherStudent.getInstanceName());

Should it say myStudent or anotherStudent? Obviously, it has no clue. Or funnier situations:

School mySchool = new School("Harvard");
mySchool.enroll(new Student("John"));
Console.Write(mySchool.students[0].getInstanceName());

I really would like to know what this would print out.

1 Comment

It's not that ridiculous. These problems can all be reconciled by stipulating that the value returned should be the name of the variable or identifier used to dereference the object and call the method. It's already possible to obtain the line number of the calling code, the name of the calling method etc. I appreciate this isn't feasible under the CLR due to the way symbols are managed as @Reed Copsey states, but it's hardly ridiculous. I can answer your question: "students[0]"!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.