2012-04-17 34 views
7

Có một số bài kiểm tra đơn vị trong dự án của tôi, nơi chúng tôi muốn có thể thiết lập một số thuộc tính có trình cài đặt riêng. Hiện nay tôi đang làm việc đó thông qua phản ánh và phương pháp mở rộng này:Làm cách nào để chuyển thuộc tính qua biểu thức lambda?

public static void SetPrivateProperty(this object sourceObject, string propertyName, object propertyValue) 
{ 
    sourceObject.GetType().GetProperty(propertyName).SetValue(sourceObject, propertyValue, null); 
} 

Giả sử tôi đã có một TestObject như thế này:

public class TestObject 
{ 
    public int TestProperty{ get; private set; } 
} 

Sau đó tôi có thể gọi đây là trong các thử nghiệm đơn vị của tôi như sau:

myTestObject.SetPrivateProperty("TestProperty", 1); 

Tuy nhiên, tôi muốn xác thực tên thuộc tính tại thời gian biên dịch và do đó tôi muốn có thể chuyển thuộc tính qua biểu thức, như sau:

myTestObject.SetPrivateProperty(o => o.TestProperty, 1); 

Tôi làm cách nào để thực hiện việc này?

+0

mục đích của biểu thức lambda là gì? Để cung cấp xác nhận thời gian biên dịch? – mellamokb

+0

@mellamokb Có. Nếu có cách khác để làm điều đó, tôi là game. – Sterno

+0

Xem http://stackoverflow.com/questions/671968/retrieving-property-name-from-lambda-expression – phoog

Trả lời

9

Nếu trình thu thập dữ liệu được công khai, thì những điều sau đây sẽ hoạt động. Nó sẽ cung cấp cho bạn một phương pháp tiện ích mở rộng như sau:

var propertyName = myTestObject.NameOf(o => o.TestProperty); 

Nó yêu cầu bộ thu công cộng. Tôi hy vọng, tại một số điểm, chức năng phản chiếu như thế này được cuộn vào ngôn ngữ.

public static class Name 
{ 
    public static string Of(LambdaExpression selector) 
    { 
     if (selector == null) throw new ArgumentNullException("selector"); 

     var mexp = selector.Body as MemberExpression; 
     if (mexp == null) 
     { 
      var uexp = (selector.Body as UnaryExpression); 
      if (uexp == null) 
       throw new TargetException(
        "Cannot determine the name of a member using an expression because the expression provided cannot be converted to a '" + 
        typeof(UnaryExpression).Name + "'." 
       ); 
      mexp = uexp.Operand as MemberExpression; 
     } 

     if (mexp == null) throw new TargetException(
      "Cannot determine the name of a member using an expression because the expression provided cannot be converted to a '" + 
      typeof(MemberExpression).Name + "'." 
     ); 
     return mexp.Member.Name; 
    } 

    public static string Of<TSource>(Expression<Func<TSource, object>> selector) 
    { 
     return Of<TSource, object>(selector); 
    } 

    public static string Of<TSource, TResult>(Expression<Func<TSource, TResult>> selector) 
    { 
     return Of(selector as LambdaExpression); 
    } 
} 

public static class NameExtensions 
{ 
    public static string NameOf<TSource, TResult>(this TSource obj, Expression<Func<TSource, TResult>> selector) 
    { 
     return Name.Of(selector); 
    } 
} 
Các vấn đề liên quan