2013-12-12 17 views
6

tôi có phương pháp tĩnh như thế này:Làm thế nào Func <DomainObject, đối tượng> Tên trở lại đối tượng như chuỗi

public static string MyMethod(Func<Student, object> func) 
    {    
     return ??? ; 
    } 

và tôi sử dụng nó như sau:

var s1 = MyMethod(student => student.ID); // Return "ID" ??? 
    var s2 = MyMethod(student => student.Age); // Return "Age" ??? 
    var s3 = MyMethod(student => student.Name); // Return "Name" ??? 

Làm thế nào ghi phương pháp mà trở lại như sau các kết quả ?

  • s1: "ID"
  • s2: "Age"
  • s3: "Tên"

* trở lại mỗi tên property`s sau => như chuỗi

+6

Bạn không thể với chữ ký này - nó phải là một cái gì đó như 'Expression >'. – Jon

Trả lời

1

Bạn có thể thay đổi chữ ký của phương thức từ

public static string MyMethod(Func<Student, object> func) 

thay đổi nó để

public static string MyMethod(Expression<Func<Student, object>> func) { 
    return GetMemeberName(func) 
    } 

    public static string GetMemberName(Expression expression) 
    {    
     if (expression is LambdaExpression) 
     { 
      var lambdaExpression = (LambdaExpression)expression; 
      return GetMemberName(lambdaExpression.Body);        
     } 

     if (expression is MemberExpression) 
     { 
      var memberExpression = (MemberExpression)expression; 
      if (memberExpression.Expression.NodeType == ExpressionType.MemberAccess) 
      { 
       return GetMemberName(memberExpression.Expression)+ "."+ memberExpression.Member.Name; 
      } 
      return memberExpression.Member.Name; 
     } 

     if (expression is UnaryExpression) 
     { 
      var unaryExpression = (UnaryExpression)expression; 
      if (unaryExpression.NodeType != ExpressionType.Convert) 
       throw new Exception(string.Format(
        "Cannot interpret member from {0}", 
        expression)); 
      return GetMemberName(unaryExpression.Operand); 
     } 
     throw new Exception(string.Format("Could not determine member from {0}",expression)); 
    } 
+2

Điều này là tốt, nhưng bạn phải nói với anh ta làm thế nào để làm cho nó hoạt động. OP có 'Func <>', không phải 'Expression'. – Gabe

+4

Về cơ bản đây là một loạt các mã mà, trong khi hữu ích, đến hư không gần để trả lời câu hỏi đã nêu. Tôi sẽ upvote này nếu nó đã được thực hiện thành một câu trả lời thực sự. – Jon

+0

Cũng lưu ý rằng với tham số kiểu 'Expression', bạn không thể gọi nó bằng lambda. – Servy

0

Chữ ký phải liên quan đến cây biểu thức chứ không phải là func để có thể kiểm tra nó. May mắn thay, lời gọi của bạn không thay đổi khi trình biên dịch sẽ tạo ra các biểu thức ra khỏi lambdas của bạn.

Phiên bản này có lẽ là ngắn nhất, nó không liên quan đến đệ quy nhưng chỉ hoạt động đối với lambdas truy cập thuộc tính đơn giản.

public static string MyFunc(Expression<Func<Student, object>> Property) 
{ 
    if (Property != null && Property.Body != null) 
     if (Property.Body.NodeType == ExpressionType.MemberAccess) 
     { 
      MemberExpression memberExpression = 
       (MemberExpression)Property.Body; 

      if (!string.IsNullOrEmpty(memberExpression.Member.Name)) 
       return memberExpression.Member.Name; 

     } 

    return string.Empty; 
} 
0

Từ another SO question, điều này có thể là những gì bạn đang tìm kiếm:

public static string GetPropertyName<T>(Expression<Func<T>> propertyExpression) 
{ 
    return (propertyExpression.Body as MemberExpression).Member.Name; 
} 

Để sử dụng nó, bạn muốn viết một cái gì đó như thế này:

var propertyName = GetPropertyName(
    () => myObject.AProperty); // returns "AProperty" 
Các vấn đề liên quan