我有一个表达式,我想再插入一个节点。我发现了this SO question类似的问题,该问题在表达式的末尾添加了属性。
我对Expressions还是很陌生,我不知道在节点之间这样做。

我做了这个简单的控制台测试应用程序,以显示我遇到的问题:

public class Program
{
    private static void Main()
    {
        var provider = new Provider<Foo>();
        var foo = new Foo {Label = "myLabel", Owner = "Me"};
        provider.AddData(foo);

        provider.AddExpression(f => f.Label);

        // This writes: f => f.Label
        Console.WriteLine(provider.OriginalExpression.ToString());
        // This should write: f => f.WrappedData.Label
        // At the moment it writes: NULL
        Console.WriteLine(provider.WrapperExpression == null ? "NULL" : provider.WrapperExpression.ToString());

        Console.ReadKey();
    }
}

public class Foo
{
    public string Label { get; set; }
    public string Owner { get; set; }
}

public class Wrapper<T> where T : class
{
    public string Id { get; set; }
    public T WrappedData { get; set; }
}

public class Provider<T> where T : class
{
    public Wrapper<T> _internalWrapper = new Wrapper<T>();

    // The expression for the Property when using T (i.e. Foo)
    public Expression<Func<T, string>> OriginalExpression { get; private set; }
    // The expression for the Property when using _internalWrapper
    public Expression<Func<Wrapper<T>, string>> WrapperExpression { get; private set; }

    public void AddData(T data)
    {
        _internalWrapper = new Wrapper<T> { WrappedData = data, Id = "myId" };
    }

    public void AddExpression(Expression<Func<T, string>> valueExpression)
    {
        OriginalExpression = valueExpression;
        BuildWrapperExpression();
    }

    private void BuildWrapperExpression()
    {
        // HERE IS THE PROBLEM:
        // Here I have to insert the node "WrappedData" in the OriginalExpression and save it as WrapperExpression
        // So {f => f.Label} must result into {f => f.WrappedData.Label}
        // It should work as well for deeper nodes. I.e. when OriginalExpression is something like {f => f.Bar.Prop2.Label}
    }
}


我已经在BuildWrapperExpression()方法中尝试过查看版本,但没有一个版本提供f => f.WrappedData.Label
我得到类似
f => Invoke(value (ConsoleApplication1.Provide1+<>c__DisplayClass1[ConsoleApplication1.Foo]).lambda, f.WrappedData)
x => Invoke(f => f.Label, Invoke(e => e.WrappedData, x))

对于我来说,表达式的进一步使用必须是x => x.WrappedData.Label

非常感谢

最佳答案

您不能简单地:

private void BuildWrapperExpression()
{
    var lambda = OriginalExpression.Compile();
    WrapperExpression = x => lambda(x.WrappedData);
}


或者,您可以实现一个ExpressionVistor。检查马克的答案:https://stackoverflow.com/a/9132775/1386995

10-04 12:18