2012-04-17 10 views
7

私のプロジェクトにはプライベートセッターを持ついくつかのプロパティを設定できるユニットテストがいくつかあります。現在、私は反射し、この拡張メソッドを経由して、それをやっている:ラムダ式でプロパティを渡すにはどうしたらいいですか?

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

を私はTestObjectはこのようにしていたと仮定すると、次のように

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

私はその後、私のユニットテストでこれを呼び出すことができます。

myTestObject.SetPrivateProperty("TestProperty", 1); 

しかし、私はコンパイル時にプロパティ名の検証をしたいので、次のようにvia式でプロパティを渡すことができます:

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

どうすればいいですか?

+0

は、ラムダ式の目的は何ですか?コンパイル時の検証を提供するには? – mellamokb

+0

@mellamokbはい。それを行う別の手段があるなら、私はゲームです。 – Sterno

+0

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

答えて

9

getterが公開されている場合、次のように動作するはずです。

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

パブリックゲッターが必要です。これは、次のような拡張メソッドを提供します。ある時点で、このようなリフレクション機能が言語に組み込まれることを願っています。 C#6.0に

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); 
    } 
} 
関連する問題