如何使用表达式设置属性值? [英] How to set property value using Expressions?

查看:127
本文介绍了如何使用表达式设置属性值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

 公共静态无效SetPropertyValue(对象的目标,字符串作为propName,对象的值)
:考虑下面的方法

{
VAR propInfo = target.GetType()的getProperty(作为propName,
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic可| BindingFlags.DeclaredOnly)。

如果(propInfo == NULL)
抛出新ArgumentOutOfRangeException(作为propName,没有目标找到物业);
,否则
propInfo.SetValue(目标,价值,NULL);
}

您会如何去写它的表情启用相当于无需在传递对目标额外的参数?



为什么这样做,而不是设置属性直接我能听到你说。例如,假设我们有一个具有公共的getter但私人二传手属性下面的类:

 公共类客户
{
公共字符串名称{搞定;私人集;}
公共字符串名称{;设置;}
}



我希望能够调用:



  VAR myCustomerInstance =新客户(); 
SetPropertyValue<客户>(卡斯特= GT; myCustomerInstance.Title,先生);

现在这里是一些示例代码。

 公共静态无效SetPropertyValue< T>(表达式来; Func键< T,对象>> memberLamda,对象的值)
{
MemberExpression memberSelectorExpression;
VAR selectorExpression = memberLamda.Body;
VAR castExpression = selectorExpression为UnaryExpression;

如果(castExpression!= NULL)
memberSelectorExpression = castExpression.Operand为MemberExpression;
,否则
memberSelectorExpression = memberLamda.Body为MemberExpression;

//我如何获得myCustomerInstance的值,这样我可以调用的SetValue在把它当作一个参数?是否有可能

}



任何指针?


解决方案

您能欺骗,让生活更容易使用的扩展方法:

 公共静态类LambdaExtensions 
{
公共静态无效SetPropertyValue< T>(这件T目标,表达< Func键< T,对象>> memberLamda,对象值)
{
VAR memberSelectorExpression = memberLamda.Body为MemberExpression;
如果(!memberSelectorExpression = NULL)
{
VAR财产= memberSelectorExpression.Member为的PropertyInfo;
如果(财产!= NULL)
{
property.SetValue(目标,价值,NULL);
}
}
}
}

和那么:

  VAR myCustomerInstance =新客户(); 
myCustomerInstance.SetPropertyValue(C => c.Title,先生);

之所以这样是比较容易的,因为你已经在其上调用扩展方法的对象。另外,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>(this T target, Expression<Func<T, object>> memberLamda, object 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 though to get to the underlying target and PropertyInfo.

这篇关于如何使用表达式设置属性值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆