2013-05-03 29 views
10

Có lẽ, câu hỏi này là ngu ngốc, nhưng trong tình hình cụ thể của tôi, tôi muốn để có được tên Ví dụ, vì vậy những gì tôi có nghĩa là:Nhận tên instance C#

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

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

    public getInstanceName() 
    { 
     //some function 
    } 

} 

nên khi tôi làm một sinh viên

Student myStudent = new Student("John"); 

thật ngu ngốc nhưng tôi muốn điều này

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

Vì vậy, bạn muốn tên của biến? –

+3

Bạn muốn điều đó làm gì? không có nghĩa lý gì. –

+0

Bạn có muốn tên biến e..g 'myStudent' hay tên của sinh viên, ví dụ: 'John'? – eandersson

Trả lời

9

Điều này không thể thực hiện được trong C#. Khi chạy, các tên biến sẽ không tồn tại, vì JIT sẽ loại bỏ thông tin ký hiệu. Ngoài ra, biến là một tham chiếu đến cá thể lớp - nhiều biến có thể tham chiếu cùng một cá thể và một cá thể có thể được tham chiếu bởi các biến có tên khác nhau trong suốt vòng đời của nó.

1

Không, điều này là không thể, bởi vì nó hoàn toàn vô lý. Một đối tượng có thể không bao giờ, theo bất kỳ cách nào, biết tên của biến mà bạn tình cờ gán cho nó. Hãy tưởng tượng:

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

nó có nên nói myStudent hoặc anotherStudent? Rõ ràng, nó không có đầu mối. Hoặc các tình huống thú vị hơn:

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

Tôi thực sự muốn biết điều này sẽ in ra.

+2

Nó không phải là vô lý. Những vấn đề này tất cả có thể được điều chỉnh bằng cách quy định rằng giá trị trả về phải là tên của biến hoặc định danh được sử dụng để dereference đối tượng và gọi phương thức. Nó đã có thể để có được số dòng của mã gọi điện thoại, tên của phương pháp gọi vv Tôi đánh giá cao điều này là không khả thi theo CLR do cách các biểu tượng được quản lý như tiểu bang @ Copeed Copsey, nhưng nó hầu như vô lý. Tôi có thể trả lời câu hỏi của bạn: "sinh viên [0]"! –

3

này cung cấp cho một thử

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

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

Hoặc

GetName(new { myStudent }); 

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

+1 từ tôi - Đây là một cách tiếp cận thú vị. Lưu ý rằng nó không thực sự nhận được tên biến, nhiều như tạo một kiểu mới với một biến để phù hợp với nó trong một trường hoặc thuộc tính và tìm nạp nó. Hoạt động trong hầu hết các trường hợp (bạn có thể phá vỡ điều này, nhưng nói chung, một cách tiếp cận thú vị). –

1

Tên biến chỉ tồn tại vì lợi ích của bạn trong khi mã hóa. Khi mã được biên dịch, tên myStudent không còn tồn tại nữa. Bạn có thể theo dõi các tên instance trong một từ điển, như thế này:

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

Không, nhưng bạn có thể làm điều này

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

này bây giờ có thể trong C# 6.0:

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

này rất hữu ích cho các Hợp đồng Mã và ghi nhật ký lỗi vì nó có nghĩa là nếu bạn sử dụng "myStudent" trong thông báo lỗi của bạn và sau đó quyết định đổi tên "myStudent", bạn sẽ bị trình biên dịch buộc phải thay đổi tên trong m cũng tốt hơn là có thể quên nó.

+1

FYI C# 6.0! = .net 4.6, do đó, bây giờ có thể với C# 6.0'. Phiên bản C# bạn đang sử dụng dựa trên sự hỗ trợ của trình biên dịch => IDE. Để viết bằng C# 6.0, bạn cần Visual Studio 2015. – Athafoud

+0

@Athafoud cảm ơn vì đã sửa :) – elexis

4

Câu hỏi này rất cũ, nhưng câu trả lời đã thay đổi với bản phát hành .Net Framework 4.6. Hiện tại có một toán tử nameof(..) có thể được sử dụng để lấy giá trị chuỗi của tên biến tại thời gian biên dịch.

Vì vậy, đối với câu hỏi gốc C# nameof(myStudent) // returns "myStudent"

Các vấn đề liên quan