How to pass property through lambda expression?

My project has separate unit tests in which we want to set some properties that have private setters. I am currently doing this through reflection and this extension method:

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

Assuming I have a TestObject like this:

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

Then I can call it in my unit tests as follows:

 myTestObject.SetPrivateProperty("TestProperty", 1); 

However, I would like to have the property name validation at compile time, and therefore I would like to pass the property in the expression through the expression, for example:

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

How can i do this?

+7
source share
2 answers

New for C # 6.0: nameof (property)

+4
source

If the recipient is publicly available, then the following should work. It will give you an extension method that looks like this:

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

This requires a public receiver. Hopefully, at some point, reflection functionality like this is turned over to the language.

 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); } } 
+9
source

All Articles