我正在尝试使用Expression.Dynamic()来构建一个赋值操作...我想用它来有选择地为我的语言中的某些自定义类型实例提供值类型语义。我不能用"static“(?)表达式,因为我不知道实际的类型是什么(我需要MetaObject实例及其LimitType...因此,Expression.Dynamic() )。
这对我没用..。如果使用Expression.Assign()从我的OperationBinder子类构建一个MetaObject,那么它不会做任何事情。
头。敲打着。在……上面。课桌。为。几个小时。
只是想知道这是不是一个受支持的行为,或者我是不是找错了地方?
谢谢..。
发布于 2009-01-07 03:53:39
我认为你基本上有两个选择。但是,无论在哪种情况下,您都应该使用定制绑定器,而不是OperationBinder的子类。这是因为您没有执行跨语言操作。相反,您正在实现语言语义的一部分,但只想要好的DLR内容。您应该子类MetaObjectBinder来实现这一点(在较早的构建中为MetaAction)。
因此,您有两种选择,一种是使用Ast.Dynamic返回分配给本地变量的新值,另一种是将该值作为ref参数传递。这些代码应该如下所示:
Ast.Assign(localVal, Ast.Dynamic(new AssignBinder(...), localVal, newVal);
or
delegate void AssignDelegate<TLocal, TValue>(CallSite site, TLocal loc, TValue val);
Type dlgType = typeof(AssignDelegate).MakeGenericType(new Type[] { localVal.Type, newVal.Type });
Ast.Dynamic(dlgType, new AssignBinder(...), localVal, newVal);在你的绑定器中,你将覆盖Bind方法,它将给你提供传入的MetaObject,对于第一个元对象,你只需要返回新值,对于第二个绑定方法,你只需要将其赋值给第一个MetaObject。
我还没有尝试过,但这基本上就是它应该是如何工作的。
发布于 2009-01-06 07:54:55
你能澄清一下确切的场景吗?我非常熟悉Expression,对在DLR / 4.0中使用它也还算熟悉,但我不是100%确定你想要做什么。还要注意的是,不管是C#还是原始树,这种用法都有一些limitations。
发布于 2009-11-07 20:04:24
如果要创建赋值表达式,只需创建一个调用通用赋值例程的表达式。下面的类提供了一个很好的扩展方法,可以将任何字段访问表达式转换为字段赋值表达式:
using System;
using System.Linq.Expressions;
using System.Reflection;
namespace Ethica.Expressions
{
public static class ExpressionExtenstions
{
private class AssignmentHelper<T>
{
private static void SetValue(ref T target, T value)
{
target = value;
}
internal static MethodInfo MethodInfoSetValue =
typeof(AssignmentHelper<T>).GetMethod("SetValue", BindingFlags.NonPublic | BindingFlags.Static);
}
public static Expression<Action<TInstance, TProp>> ToFieldAssignExpression<TInstance, TProp>
(
this Expression<Func<TInstance, TProp>> 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");
ParameterExpression[] parms = new ParameterExpression[] {
fieldGetter.Parameters[0],
Expression.Parameter(typeof(TProp), "value")};
Expression body = Expression.Call(AssignmentHelper<TProp>.MethodInfoSetValue,
new Expression[] { fieldGetter.Body, parms[1] });
return Expression.Lambda<Action<TInstance, TProp>>(body, parms);
}
public static Action<TInstance, TProp> ToFieldAssignment<TInstance, TProp>
(
this Expression<Func<TInstance, TProp>> fieldGetter
)
{
return fieldGetter.ToFieldAssignExpression().Compile();
}
}
}https://stackoverflow.com/questions/415654
复制相似问题