从行动中获取MemberAssignments

时间:2014-05-09 08:04:48

标签: c# .net-4.0 expression-trees

我正在尝试构建一个可以从强类型语句体中捕获赋值的方法。方法调用应该如下所示:

myObject.Assign(o =>
                {
                    o.SomeProperty = 1;
                    o.AnotherProperty = "two";
                });

我想得到一份作业清单;一组MemberAssignment个实例似乎很合适。

我不清楚Assign()的方法标题需要看起来像什么。

以下是我目前的情况:

public class MyClass
{
    public void Assign(System.Linq.Expressions.Expression<System.Action<MyBunchOfProps>> assignments)
    {

    }
}

public struct MyBunchOfProps
{
    public int SomeProperty { get; set; }
    public string AnotherProperty { get; set; }
}

使用语句主体和多个赋值,我得到“带有语句主体的lambda表达式无法转换为表达式树”。

如果我省略语句体并且只做一个赋值(myObject.Assign(o => o.SomeProperty = 1);),我改为“表达式树可能不包含赋值运算符”。

我是否需要使用其他类而不是Expression

1 个答案:

答案 0 :(得分:2)

分析包含一堆赋值的表达式树会很容易,但不幸的是,C#不支持通过 lambdas 创建带有赋值或语句的表达式树,因为编译错误表明。

我建议你构造一个自定义对象,它可以包含(成员访问lambda,object)元组的列表并使用它。

例如,您应该能够创建一个允许这种语法的类:

var list = new AssignmentList<MyBunchOfProps>
           {
               { o => o.SomeProperty, 1 },
               { o => o.AnotherProperty,  "two" }
           };

以下是此示例实现:

public class AssignmentList<T> : IEnumerable<Tuple<LambdaExpression, object>>
{
    private readonly List<Tuple<LambdaExpression, object>> _list 
            = new List<Tuple<LambdaExpression, object>>();

    public void Add<TProperty>(Expression<Func<T, TProperty>> selector, TProperty value)
    {
        _list.Add(Tuple.Create<LambdaExpression, object>(selector, value));       
    }

    public IEnumerator<Tuple<LambdaExpression, object>> GetEnumerator()
    {
        return _list.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    { 
        return GetEnumerator();
    }
}