2013-05-03 65 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

所以,你想要的變量的名稱? – 2013-05-03 16:39:07

+3

你想要什麼?這個不成立。 – 2013-05-03 16:39:56

+0

你想要變量e..g'myStudent'的名字還是學生的名字例如'John'? – eandersson 2013-05-03 16:40:10

回答

9

這是不可能在C#中。在運行時,變量名稱將不存在,因爲JIT刪除符號信息。

此外,變量是對類實例的引用 - 多個變量可以引用同一個實例,並且實例可以在其整個生命週期中由不同名稱的變量引用。

1

不,這是不可能的,因爲這完全荒謬。一個對象永遠無法知道你分配給它的變量的名字。試想一下:

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

它應該說myStudentanotherStudent?顯然,它沒有線索。或更有趣的情況:

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

我真的很想知道這會打印出來。

+2

這並不是那麼荒謬。這些問題都可以通過規定返回的值應該是用於取消引用對象並調用方法的變量或標識符的名稱來協調。已經有可能獲得調用代碼的行號,調用方法的名稱等。我感謝這在CLR下是不可行的,因爲符號是以@Reed Copsey狀態管理的方式,但這並不可笑。 我可以回答你的問題:「學生[0]」! – 2015-02-26 16:29:54

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 from me - 這是一個有趣的方法。請注意,它實際上並沒有獲取變量名稱,就像創建一個帶有變量的新類型以在字段或屬性中匹配它並獲取它一樣。在大多數情況下工作(你可以打破這一點,但總的來說,一個有趣的方法)。 – 2013-05-03 16:46:26

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

僅供參考C#6.0!= .net 4.6,所以'這現在可以用C#6.0'。您正在使用的C#版本基於編譯器support => IDE。要在C#6.0中編寫,您需要Visual Studio 2015. – Athafoud 2016-05-27 08:36:37

+0

@Athafoud感謝您的更正:) – elexis 2016-05-28 00:02:12

4

這個問題很舊,但答案隨着.Net Framework 4.6的發佈而改變。現在有一個nameof(..)運算符,它可用於在編譯時獲取變量名稱的字符串值。

所以對於原來的問題C# nameof(myStudent) // returns "myStudent"