【问题标题】:Create Expression Tree dynamically动态创建表达式树
【发布时间】:2019-05-02 19:44:22
【问题描述】:

我有一个想法,想知道它是否可行。 我有一个带有属性的简单类,并希望使用表达式生成访问器。 但最后我需要得到一个Func<Test, string>,但我不知道我使用它们时的类型。 一个小例子

class Program
{
    static void Main(string[] args)
    {
        Test test = new Test();
        test.TestString = "Blubb";
        var actionStub = typeof(Helper).GetMethod("CreatePropertyGetter").MakeGenericMethod(new Type[] { test.GetType(), typeof(string)});
        dynamic action = actionStub.Invoke(null, new object[] {test.GetType(), "TestString"});

        var x = action(test);
    }
}

public class Test
{
    public string TestString { get; set; }
}

public static class Helper
{
    public static Func<TType, TPropValueType> CreatePropertyGetter<TType, TPropValueType>(Type type,
                                                                                  string propertyName)
    {
        PropertyInfo fieldInfo = type.GetProperty(propertyName);
        ParameterExpression targetExp = Expression.Parameter(typeof(TType), "target");

        MemberExpression fieldExp = Expression.Property(targetExp, fieldInfo);
        UnaryExpression assignExp = Expression.Convert(fieldExp, typeof(TPropValueType));

        Func<TType, TPropValueType> getter =
            Expression.Lambda<Func<TType, TPropValueType>>(assignExp, targetExp).Compile();

        return getter;
    }
}

问题是我不能调用没有动态的表达式,因为我不能简单地将它转换为Func&lt;object, object&gt;

【问题讨论】:

    标签: c# lambda expression-trees


    【解决方案1】:

    您正在生成(TType target) =&gt; target.Something。而是生成(object target) =&gt; (object)((TType)target).Something,以便您可以使用Func&lt;object, object&gt;

    【讨论】:

    • 谢谢你能再解释一下吗?
    • 您要创建一个Func&lt;object, object&gt;,因此参数和正文必须符合该签名。参数必须是 object 类型,并且 body 必须返回 object。然后你可以使用 Func.
    【解决方案2】:

    不清楚你到底要什么,但这里有一个例子,你如何做到这一点Func&lt;object, object&gt;

    public static class Helper
    {
        public static Func<object, object> CreatePropertyGetter(Type type, string propertyName)
        {
            var fieldInfo = type.GetProperty(propertyName);
            var targetExp = Expression.Parameter(typeof(object), "target");
            var fieldExp = Expression.Property(Expression.ConvertChecked(targetExp, type), fieldInfo);
            var getter = Expression.Lambda<Func<object, object>>(fieldExp,targetExp).Compile();
            return getter;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多