使用正确的类型调用委托

  • 本文关键字:调用 类型 c# linq
  • 更新时间 :
  • 英文 :


我有一个对象类型的参数。可以在该参数上设置任何内容。我需要在该参数中找到具有特定名称的属性。当然,如果它存在的话。

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

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, ...)

但是这会将System.Delegate返回给我,我需要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 在这里不是一个选项。它太慢了。我试了试。

要考虑的两个选项:

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

    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);
    }
    
  • 将属性表达式包装在表达式树中的转换表达式中:

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

这两种情况都假定您很少执行创建,然后使用相同类型的值多次调用委托。它们可能是您所需要的,也可能不是您需要的 - 很难用弱要求来判断。当然,它们确实要求您稍后调用函数的值属于正确的类型。

也许这将满足您的需求:

Expression.Lambda(Type, Expression, IEnumerable<ParameterExpression>)
          .Compile()
          .DynamicInvoke(...)

相关内容

  • 没有找到相关文章

最新更新