c# - 如何使用表达式设置属性值?

标签 c# linq expression

<分区>

给定以下方法:

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);
}

您将如何着手编写启用表达式的等效项,而无需为目标传递额外的参数?

为什么要这样做而不是直接设置属性我能听到你说。例如,假设我们有以下类,其属性具有公共(public) getter 但私有(private) setter:

public class Customer 
{
   public string Title {get; private set;}
   public string Name {get; set;}
}

我希望能够调用:

var myCustomerInstance = new Customer();
SetPropertyValue<Customer>(cust => myCustomerInstance.Title, "Mr");

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

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

}

有什么指点吗?

最佳答案

您可以使用扩展方法作弊并让生活更轻松:

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);
            }
        }
    }
}

然后:

var myCustomerInstance = new Customer();
myCustomerInstance.SetPropertyValue(c => c.Title, "Mr");

之所以这样比较容易,是因为您已经有了调用扩展方法的目标。 lambda 表达式也是一个没有闭包的简单成员表达式。在您的原始示例中,目标是在闭包中捕获的,到达底层目标和 PropertyInfo 可能有点棘手。

关于c# - 如何使用表达式设置属性值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9601707/

相关文章:

c++ - 为什么在构造字符串时 `std::istreambuf_iterator<char>`被视为函数声明?

c# - 如何在C#中将字符串分隔成数组?

c# - DbSet<>.Local 是否需要特别小心使用?

c# - nopCommerce 程序集找不到 dll 引用

vb.net - 如何使用 LINQ 过滤嵌套类的集合以生成这些类的唯一属性的字典?

syntax - 是否可以在 Powerbuilder 的表达式中使用列属性?

c# - EF : When executing a command, 参数必须完全是数据库参数或值

c# - 如何使用 Linq 从 jArray 访问元素

c# - 为什么在 Entity Framework 中使用数据结构更好

python - yield 和返回有何不同?