2013-05-03 4 views
10

Может быть, этот вопрос глупый, но в моей конкретной ситуации я хочу, чтобы получить имя экземпляра, так что я имею в виду:Получить имя экземпляра C#

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

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

    public getInstanceName() 
    { 
     //some function 
    } 

} 

поэтому, когда я сделать студент

Student myStudent = new Student("John"); 

это глупо, но я хочу это

myStudent.getInstanceName(); // it should return 'myStudent' 
+1

Так что вы хотите имя переменной? –

+3

Для чего вы хотите? это не имеет никакого смысла. –

+0

Вы хотите, чтобы имя переменной e..g 'myStudent', или имя студента, например. 'John'? – eandersson

ответ

9

Это не возможно в C#. Во время выполнения имена переменных даже не существуют, поскольку JIT удаляет информацию о символе.

Кроме того, переменная является ссылкой на экземпляр класса - несколько переменных могут ссылаться на один и тот же экземпляр, а на экземпляр могут ссылаться переменные разных имен на протяжении всего срока его службы.

1

Нет, это невозможно, потому что это совершенно смешно. Объект никогда не может, каким-либо образом, знать имя переменной, которой вы ее назначили. Представьте себе:

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

Должен ли он сказать myStudent или anotherStudent? Очевидно, это не имеет понятия. Или смешные ситуации:

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

Я действительно хотел бы знать, что это будет печатать.

+2

Это не так уж и смешно. Эти проблемы можно согласовать, указав, что возвращаемое значение должно быть именем переменной или идентификатора, используемого для разыменования объекта и вызова метода. Уже можно получить номер строки вызывающего кода, имя вызывающего метода и т. Д. Я считаю, что это невозможно в рамках CLR из-за того, что символы управляются как @Reed Copsey, но это почти нелепо. Я могу ответить на ваш вопрос: «студенты [0]»! –

3

Дайте этому попытку

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

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

Или

GetName(new { myStudent }); 

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

+1 от меня - это интересный подход. Обратите внимание, что на самом деле это не получение имени переменной, а также создание нового типа с переменной, которая соответствует ему в поле или свойстве, и получение этого. Работает в большинстве случаев (вы можете сломать это, но в целом, интересный подход). –

1

имена переменных существуют только в вашу пользу при кодировании. После компиляции кода имя myStudent больше не существует. Вы можете отслеживать имена экземпляров в словарь, например:

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" 
1

Нет, но вы можете сделать это

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

Теперь это возможно в C# 6.0:

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

Это полезно для кодовых контрактов и регистрации ошибок, так как это означает, что если вы используете «myStudent» в своем сообщении об ошибке, а позже решили переименовать «myStudent», вы будете вынуждены компилятором изменить имя в m а также, а не забывать об этом.

+1

FYI C# 6.0! = .net 4.6, поэтому 'Теперь это возможно с C# 6.0'. Версия C#, которую вы используете, основана на поддержке компилятора => IDE. Для написания на C# 6.0 вам нужна Visual Studio 2015. – Athafoud

+0

@Athafoud благодарит за исправление :) – elexis

4

Этот вопрос очень старый, но ответ изменился с выходом .Net Framework 4.6. В настоящее время существует оператор nameof(..), который может использоваться для получения строкового значения имени переменных во время компиляции.

Так что для первоначального вопроса C# nameof(myStudent) // returns "myStudent"

Смежные вопросы