当前位置:  开发笔记 > 编程语言 > 正文

.NET 3.5表达式树中的赋值

如何解决《.NET3.5表达式树中的赋值》经验,为你挑选了3个好方法。

是否可以将赋值编码到表达式树中?



1> Jon Skeet..:

不,我不相信.

当然,转换lambda表达式时C#编译器不允许它:

int x;
Expression> foo = (x=y); // Assign to x and return value

这会产生错误:

CS0832: An expression tree may not contain an assignment operator



2> Jirapong..:

你应该能够使用.NET 4.0 Library.通过将Microsoft.Scripting.Core.dll导入.NET 3.5项目.

我正在使用DLR 0.9 - 版本1.0中的Expession.Block和Expression.Scope可能会有一些变化(您可以参考http://www.codeplex.com/dlr/Thread/View.aspx?ThreadId=43234的参考资料)

以下示例将向您展示.

using System;
using System.Collections.Generic;
using Microsoft.Scripting.Ast;
using Microsoft.Linq.Expressions;
using System.Reflection;

namespace dlr_sample
{
    class Program
    {
        static void Main(string[] args)
        {
            List statements = new List();

            ParameterExpression x = Expression.Variable(typeof(int), "r");
            ParameterExpression y = Expression.Variable(typeof(int), "y");

            statements.Add(
                Expression.Assign(
                    x,
                    Expression.Constant(1)
                )
             );

            statements.Add(
                Expression.Assign(
                    y,
                    x
                )
             );

            MethodInfo cw = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(int) });

            statements.Add(
                Expression.Call(
                    cw,
                    y
                )
            );

            LambdaExpression lambda = Expression.Lambda(Expression.Scope(Expression.Block(statements), x, y));

            lambda.Compile().DynamicInvoke();
            Console.ReadLine();
        }
    }
}



3> Mark..:

我的扩展方法正是这样做的:

/// 
/// Provides extensions for converting lambda functions into assignment actions
/// 
public static class ExpressionExtenstions
{
    /// 
    /// Converts a field/property retrieve expression into a field/property assign expression
    /// 
    /// The type of the instance.
    /// The type of the prop.
    /// The field getter.
    /// 
    public static Expression> ToFieldAssignExpression
        (
        this Expression> fieldGetter
        )
    {
        if (fieldGetter == null)
            throw new ArgumentNullException("fieldGetter");

        if (fieldGetter.Parameters.Count != 1 || !(fieldGetter.Body is MemberExpression))
            throw new ArgumentException(
                @"Input expression must be a single parameter field getter, e.g. g => g._fieldToSet  or function(g) g._fieldToSet");

        var parms = new[]
                        {
                            fieldGetter.Parameters[0],
                            Expression.Parameter(typeof (TProp), "value")
                        };

        Expression body = Expression.Call(AssignmentHelper.MethodInfoSetValue,
                                          new[] {fieldGetter.Body, parms[1]});

        return Expression.Lambda>(body, parms);
    }


    public static Action ToFieldAssignment
        (
        this Expression> fieldGetter
        )
    {
        return fieldGetter.ToFieldAssignExpression().Compile();
    }

    #region Nested type: AssignmentHelper

    private class AssignmentHelper
    {
        internal static readonly MethodInfo MethodInfoSetValue =
            typeof (AssignmentHelper).GetMethod("SetValue", BindingFlags.NonPublic | BindingFlags.Static);

        private static void SetValue(ref T target, T value)
        {
            target = value;
        }
    }

    #endregion
}

推荐阅读
女女的家_747
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有