创建属性设置器委托

Creating a property setter delegate(创建属性设置器委托)
本文介绍了创建属性设置器委托的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经创建了将属性 lambda 转换为委托的方法:

I have created methods for converting a property lambda to a delegate:

public static Delegate MakeGetter<T>(Expression<Func<T>> propertyLambda)
{
    var result = Expression.Lambda(propertyLambda.Body).Compile();
    return result;
}

public static Delegate MakeSetter<T>(Expression<Action<T>> propertyLambda)
{
    var result = Expression.Lambda(propertyLambda.Body).Compile();
    return result;
}

这些工作:

Delegate getter = MakeGetter(() => SomeClass.SomeProperty);
object o = getter.DynamicInvoke();

Delegate getter = MakeGetter(() => someObject.SomeProperty);
object o = getter.DynamicInvoke();

但这些不会编译:

Delegate setter = MakeSetter(() => SomeClass.SomeProperty);
setter.DynamicInvoke(new object[]{propValue});

Delegate setter = MakeSetter(() => someObject.SomeProperty);
setter.DynamicInvoke(new object[]{propValue});

MakeSetter 行失败并显示无法从用法推断类型参数.尝试显式指定类型参数."

The MakeSetter lines fail with "The type arguments cannot be inferred from the usage. Try specifying the type arguments explicitly."

我正在尝试做的事情可能吗?提前致谢.

Is what I'm trying to do possible? Thanks in advance.

推荐答案

Expression API 在 .NET 4.0 中支持此功能,但遗憾的是 C# 编译器没有添加任何额外的支持.但好消息是,您可以轻松获取get"表达式(C# 编译器可以编写)并将其重写为set"表达式.

The Expression API supports this in .NET 4.0, but sadly the C# compiler doesn't add any extra candy to support. But the good news is that you can trivially take a "get" expression (which the C# compiler can write) and re-write it as a "set" expression.

甚至更好;如果您没有 .NET 4.0,仍然有至少另外两种通过写为get"的表达式来执行set"的方法.

And even better; if you don't have .NET 4.0, there are still at least two other ways of performing a "set" via an expression written as a "get".

他们都在这里,供参考:

Here they all are, for info:

using System;
using System.Linq.Expressions;
using System.Reflection;
class Foo {
    public string Bar { get; set; }
    static void Main() {
        // take a "get" from C#
        Expression<Func<Foo, string>> get = foo => foo.Bar;

        // re-write in .NET 4.0 as a "set"
        var member = (MemberExpression)get.Body;
        var param = Expression.Parameter(typeof(string), "value");
        var set = Expression.Lambda<Action<Foo, string>>(
            Expression.Assign(member, param), get.Parameters[0], param);

        // compile it
        var action = set.Compile();
        var inst = new Foo();
        action(inst, "abc");
        Console.WriteLine(inst.Bar); // show it working

        //==== reflection
        MethodInfo setMethod = ((PropertyInfo)member.Member).GetSetMethod();
        setMethod.Invoke(inst, new object[] { "def" });
        Console.WriteLine(inst.Bar); // show it working

        //==== Delegate.CreateDelegate
        action = (Action<Foo, string>)
            Delegate.CreateDelegate(typeof(Action<Foo, string>), setMethod);
        action(inst, "ghi");
        Console.WriteLine(inst.Bar); // show it working
    }
}

这篇关于创建属性设置器委托的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

DispatcherQueue null when trying to update Ui property in ViewModel(尝试更新ViewModel中的Ui属性时DispatcherQueue为空)
Drawing over all windows on multiple monitors(在多个监视器上绘制所有窗口)
Programmatically show the desktop(以编程方式显示桌面)
c# Generic Setlt;Tgt; implementation to access objects by type(按类型访问对象的C#泛型集实现)
InvalidOperationException When using Context Injection in ASP.Net Core(在ASP.NET核心中使用上下文注入时发生InvalidOperationException)
LINQ many-to-many relationship, how to write a correct WHERE clause?(LINQ多对多关系,如何写一个正确的WHERE子句?)