Reputation: 541
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
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
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
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
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
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
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
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
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