正确类型的委托 [英] Invoke Delegate With Right Type

查看:49
本文介绍了正确类型的委托的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个object类型的参数.可以在该参数上设置任何内容.我需要在该参数中找到具有特定名称的属性.当然可以.

I have a parameter of type object. Anything can be set on that parameter. And I need to find the property with a certain name in that parameter. If it exists of course.

我需要这样的东西(伪代码):

I need something like this (pseudo code):

ParameterExpression arg = Expression.Parameter(parameter.GetType(), "x");
Expression expr = Expression.Property(arg, "Info");

var propertyResolver = Expression.Lambda<Func<parameter.GetType, object>>(expr, arg).Compile();

已经有方法`Expression.Lambda(Type,Expression,...)

There is already the method `Expression.Lambda(Type, Expression, ...)

但这会返回System.Delegate给我,我需要Func<>.

But that returns System.Delegate back to me and I need the Func<>.

我该怎么做?

预先感谢大家.

这是一个演示:

class Program
{
    private Func<object, object> func;

    static void Main(string[] args)
    {
        // lets say in this case the parameter is person but it could be anything
        Person parameter = new Person();

        ParameterExpression arg = Expression.Parameter(parameter.GetType(), "x");
        Expression expr = Expression.Property(arg, "Name");
        var func = Expression.Lambda<Func<parameter.GetType, object>>(expr, arg).Compile();
    }
}

class Person
{
    public string Name { get; set; }
}

创建函数后,我必须在另一个方法内的for循环中调用它至少1000次,因此此处不是DynamicInvoke的选项.它太慢了.我尝试一下.

After I created my function I have to call it at least 1000 times in an for loop inside another method therefore DynamicInvoke is not an option here. Its too slow. I try it out.

推荐答案

要考虑的两个选项:

  • 使用动态类型调用泛型方法,该方法将为您返回Func<object, object>,您稍后可以通过包装表达式树编译的委托来使用它:

  • Use dynamic typing to call a generic method which will return you a Func<object, object> which you can use later by wrapping up an expression-tree-compiled delegate:

public Func<Object, Object> CreateFunc(object sampleValue)
{
    dynamic dynamicValue = sampleValue;
    return CreateFuncImpl(dynamicValue); // Dynamic type inference
}

private Func<Object, Object> CreateFuncImpl<T>(T sampleValue)
{
    // You could use Delegate.CreateDelegate as another option - 
    // you don't need expression trees here
    var parameter = Expression.Parameter(parameter.GetType(), "x");
    var expression = Expression.Property(arg, "Name");
    var func = Expression.Lambda<Func<T, object>>(expression, parameter)
                         .Compile();
    return (object actualValue) => func((T) actualValue);
}

  • 将属性表达式包装在表达式树中的转换表达式中:

  • Wrap the property expression in a conversion expression in the expression tree:

    public Func<Object, Object> CreateFunc(object sampleValue)
    {
        var parameter = Expression.Parameter(typeof(object), "x");
        var conversion = Expression.Convert(parameter, sampleValue.GetType());
        var property = Expression.Property(conversion, "Name");
        return Expression.Lambda<Func<object, object>>(property, parameter)
                         .Compile();
    }
    

  • 这两个假设中,您很少进行创建,然后使用相同类型的值多次调用委托.它们可能不是您所需要的-很难满足需求.当然,它们确实要求您稍后使用函数调用的值是正确的类型.

    Both of these assume that you're doing the creation very rarely and then calling the delegate many times with values of the same type. They may or may not be what you need - it's hard to tell with weak requirements. They do require that the values you call the function with later are of the right type, of course.

    这篇关于正确类型的委托的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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