如何使用表达式设置属性值? [英] How to set property value using Expressions?
问题描述
给定以下方法:
public static void SetPropertyValue(object target,string propName,object value)
{
var propInfo = target.GetType()。GetProperty(propName,
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly);
if(propInfo == null)
throw new ArgumentOutOfRangeException(propName,在目标上找不到属性);
else
propInfo.SetValue(target,value,null);
}
你如何去写它的表达式启用相当于不需要传入额外的目标参数?
为什么不直接设置属性,我可以听到你说的话。例如,假设我们有一个具有public getter但是私有setter的属性的类:
public class Customer
{
public string Title {get; private set;}
public string Name {get;我想要能够调用: var myCustomerInstance = new Customer();
SetPropertyValue< Customer>(cust => myCustomerInstance.Title,Mr);
现在这里是一些示例代码。
public static void SetPropertyValue< T>(表达式< Func< T,Object>> memberLamda,对象值)
{
MemberExpression memberSelectorExpression;
var selectorExpression = memberLamda.Body;
var castExpression = selectorExpression为UnaryExpression;
if(castExpression!= null)
memberSelectorExpression = castExpression.Operand作为MemberExpression;
else
memberSelectorExpression = memberLamda.Body as MemberExpression;
//如何获取myCustomerInstance的值,以便我可以调用SetValue作为参数传递它?是否可能
}
任何指针?
解决方案您可以通过扩展方法欺骗并使生活更轻松:
public static class LambdaExtensions
{
public static void SetPropertyValue< T,TValue>(this T target,Expression< Func< T,TValue> TValue值)
{
var memberSelectorExpression = memberLamda.Body as MemberExpression;
if(memberSelectorExpression!= null)
{
var property = memberSelectorExpression.Member as PropertyInfo;
if(property!= null)
{
property.SetValue(target,value,null);
}
}
}
}
然后:
var myCustomerInstance = new Customer();
myCustomerInstance.SetPropertyValue(c => c.Title,Mr);
为什么这更容易的原因是因为已经有扩展方法被调用的目标。 lambda表达式也是一个没有闭包的简单成员表达式。在你的原始示例中,目标被捕获在一个关闭中,它可能有点棘手得到基础目标和 PropertyInfo
。
Given the following method:
public static void SetPropertyValue(object target, string propName, object value)
{
var propInfo = target.GetType().GetProperty(propName,
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly);
if (propInfo == null)
throw new ArgumentOutOfRangeException("propName", "Property not found on target");
else
propInfo.SetValue(target, value, null);
}
How would you go about writing it's expression enabled equivalent without needing to pass in an extra parameter for target?
Why do this instead of setting the property directly I can hear you say. For example suppose we have the following class with a property that has a public getter but private setter:
public class Customer
{
public string Title {get; private set;}
public string Name {get; set;}
}
I would like to be able to call:
var myCustomerInstance = new Customer();
SetPropertyValue<Customer>(cust => myCustomerInstance.Title, "Mr");
Now here is some sample code.
public static void SetPropertyValue<T>(Expression<Func<T, Object>> memberLamda , object value)
{
MemberExpression memberSelectorExpression;
var selectorExpression = memberLamda.Body;
var castExpression = selectorExpression as UnaryExpression;
if (castExpression != null)
memberSelectorExpression = castExpression.Operand as MemberExpression;
else
memberSelectorExpression = memberLamda.Body as MemberExpression;
// How do I get the value of myCustomerInstance so that I can invoke SetValue passing it in as a param? Is it possible
}
Any pointers?
解决方案 You could cheat and make life easier with an extension method:
public static class LambdaExtensions
{
public static void SetPropertyValue<T, TValue>(this T target, Expression<Func<T, TValue>> memberLamda, TValue value)
{
var memberSelectorExpression = memberLamda.Body as MemberExpression;
if (memberSelectorExpression != null)
{
var property = memberSelectorExpression.Member as PropertyInfo;
if (property != null)
{
property.SetValue(target, value, null);
}
}
}
}
and then:
var myCustomerInstance = new Customer();
myCustomerInstance.SetPropertyValue(c => c.Title, "Mr");
The reason why this is easier is because you already have the target on which the extension method is invoked. Also the lambda expression is a simple member expression without closures. In your original example the target is captured in a closure and it could be a bit tricky to get to the underlying target and PropertyInfo
.
这篇关于如何使用表达式设置属性值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!