2011-11-15 79 views
16

Một đại diện chuỗi của một tài sản trường hợp đối tượng có thể được thực hiện với Expression<Func<T>>:Có thể lấy chuỗi tên thuộc tính đối tượng mà không tạo đối tượng đối tượng không?

string propertyName = ((MemberExpression) property.Body).Member.Name; 

Nhưng nếu tôi không có (không muốn tạo) trường hợp? Làm cách nào để tôi có được tên thuộc tính trong trường hợp này?

Giải thích

Tôi cần một chuỗi đại diện của một tên sở hữu của một số đối tượng.

Hãy nói rằng có một thực thể

public class Customer 
{ 
    public int ID; 
    public string Name; 
} 

Bây giờ tôi muốn vượt qua sự biểu hiện quan trọng của tổ chức này đối với một số chức năng khác, vì vậy tôi cần chuỗi "ID", nhưng tôi không muốn hardcode chuỗi như SomeOtherFunction("ID"), thay vào đó tôi sử dụng cụm từ SomeOtherFunction(ExpressionReader.GetString(() => CustomerInstance.ID)). Để làm việc này, tôi cần cung cấp cá thể thực thể.

Bây giờ tôi muốn làm tương tự mà không cần tạo cá thể.

+0

Ý anh là gì bởi "sơ thẩm "? Bạn không cần phải tạo một thể hiện của lớp để lộ ra thuộc tính, nhưng rõ ràng là bạn cần một cá thể của 'Expression '. – CodesInChaos

+0

bạn biết về typeof (myClass) .GetProperty ("abc"), phải không? – Efrain

+0

Sự khác nhau giữa mã hóa tài sản ID và chuỗi "ID" là gì? – SWeko

Trả lời

15

này có thể với một chữ ký phương pháp như sau:

private static string GetPropertyName<TModel, TProperty>(Expression<Func<TModel, TProperty>> property) 
{ 
    MemberExpression memberExpression = (MemberExpression)property.Body; 

    return memberExpression.Member.Name; 
} 

Bạn có thể gọi phương thức này mà không có một thể hiện của lớp khách hàng:

string propertyName = GetPropertyName((Customer c) => c.ID); 

Tất nhiên bạn nên thêm một số kiểm tra cho các loại biểu thức chính xác trước khi bạn truyền tới MemberExpression và truy cập memberExpression.Member.Name.

+0

Hoạt động rất tốt, cảm ơn bạn. –

0

Tôi không chắc tôi hoàn toàn hiểu ý bạn, nhưng dựa trên hiểu biết của tôi, bạn có thể sử dụng Phản chiếu. Sử dụng phương pháp này, nếu bạn có Type về những gì bạn muốn để có được một tên thuộc tính từ, sau đó bạn có thể lấy các thuộc tính sử dụng:

Type someType = typeof(SomeClass); 

// Get all properties for a type 
PropertyInfo[] properties = someType.GetProperties(); 

// Get a property from a type by it's name 
PropertyInfo property = someType.GetProperty("PropertyName"); 

Một khi bạn đã dụ (s) của lớp PropertyInfo, bạn có thể lấy thông tin như tên thuộc tính.

Để biết thêm thông tin về phương pháp này, hãy xem MSDN Documentation.

+1

Đây không phải là những gì tôi yêu cầu . –

4

Không, bạn không cần một cá thể để phân tách Expression. Ngay cả khi biểu thức mong đợi một, bạn sẽ không bao giờ gọi nó.

Thực tế, bạn làm điều đó giống như bạn đã làm trong đoạn mã đầu tiên.

Bạn sẽ thay đổi bạn mã trông như thế này thì:

SomeOtherFunction(ExpressionReader<Customer>.GetString(c => c.ID)) 

Việc đó có ý nghĩa đối với bạn?

Hoặc:

Customer c = null; // null intentionally 

SomeOtherFunction(ExpressionReader.GetString(() => c.ID)); 

Tuy nhiên không có vấn đề là bạn không gọi biểu thức.

+0

Đề xuất đầu tiên không hoạt động. –

+0

@net_prog: Bạn sẽ phải sửa đổi mã của bạn, đó chỉ là 1 gợi ý có thể, có thể là có thể. – leppie

0

Câu trả lời được chọn là tốt nhưng không bao gồm UnaryExpressions. Nó sẽ thất bại khi cố gắng để có được tài sản của một DateTime:

private static string GetPropertyName<TModel, TProperty>(Expression<Func<TModel, TProperty>> property) 
    { 
     if (property.Body is MemberExpression) 
     { 
      return ((MemberExpression)property.Body).Member.Name; 
     } 
     else 
     { 
      var op = ((UnaryExpression)property.Body).Operand; 
      return ((MemberExpression)op).Member.Name; 
     } 
    } 
1

Với sự mới nameof điều hành của C# 6 Tôi xin đề nghị như sau:

private string GetNameMyProperty1(TestC c = null) 
{ 
    return nameof(c.MyProperty1); 
} 
+0

Bạn thậm chí không cần một thể hiện của đối tượng. Bạn chỉ có thể làm một cái gì đó như 'nameof (TestC.MyProperty1)' – jausel

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