如何通过 lambda 表达式传入属性
本文关键字:属性 表达式 何通过 lambda | 更新日期: 2023-09-27 18:31:20
在我的项目中有一些单元测试,我们希望能够设置一些具有私有资源库的属性。目前我正在通过反射和这种扩展方法来做到这一点:
public static void SetPrivateProperty(this object sourceObject, string propertyName, object propertyValue)
{
sourceObject.GetType().GetProperty(propertyName).SetValue(sourceObject, propertyValue, null);
}
假设我有一个这样的测试对象:
public class TestObject
{
public int TestProperty{ get; private set; }
}
然后,我可以在我的单元测试中调用它,如下所示:
myTestObject.SetPrivateProperty("TestProperty", 1);
但是,我想在编译时验证属性名称,因此我希望能够通过表达式传递属性,如下所示:
myTestObject.SetPrivateProperty(o => o.TestProperty, 1);
我该怎么做?
如果 getter 是公共的,那么以下内容应该可以工作。它将为您提供如下所示的扩展方法:
var propertyName = myTestObject.NameOf(o => o.TestProperty);
它需要一个公共获取者。我希望,在某个时候,像这样的反射功能被整合到语言中。
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# 6.0 的新功能:nameof(property)