是否可以将赋值编码到表达式树中?
不,我不相信.
当然,转换lambda表达式时C#编译器不允许它:
int x; Expression> foo = (x=y); // Assign to x and return value
这会产生错误:
CS0832: An expression tree may not contain an assignment operator
你应该能够使用.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) { Liststatements = 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(); } } }
我的扩展方法正是这样做的:
////// 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 }