Yoan Dinkov
Yoan Dinkov

Reputation: 541

Get instance name c#

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'

Upvotes: 16

Views: 35622

Answers (8)

KSummers
KSummers

Reputation: 32

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.

Upvotes: 1

whoisj
whoisj

Reputation: 51

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"

Upvotes: 5

elexis
elexis

Reputation: 812

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.

Upvotes: 20

Jay Byford-Rew
Jay Byford-Rew

Reputation: 6024

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

Upvotes: 1

Reed Copsey
Reed Copsey

Reputation: 564433

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.

Upvotes: 10

p.s.w.g
p.s.w.g

Reputation: 149020

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"

Upvotes: 1

Jean-Bernard Pellerin
Jean-Bernard Pellerin

Reputation: 12670

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

Upvotes: 4

Niels Keurentjes
Niels Keurentjes

Reputation: 41958

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.

Upvotes: -2

Related Questions