【发布时间】:2015-08-15 11:00:10
【问题描述】:
我有一个带有 int 字段的 ExpandoObject,我想使用表达式树将其转换为小数。
这是我正在使用的方法:
private static Expression<Func<dynamic, decimal>> CreateLambdaCastExpression()
{
// source
var sourceParameterExpression = Expression.Parameter(typeof (object), "source");
var binder = Binder.GetMember(
CSharpBinderFlags.None, "IntProp", typeof (ExpressionTreeUtils),
new[] {CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)});
// source.sourceProperty
var sourcePropertyExpression = Expression.Dynamic(
binder, typeof (object), sourceParameterExpression);
// (decimal) source;
var castedValueExpression = Expression.Convert(sourcePropertyExpression, typeof (decimal));
// () => (decimal) source;
return Expression.Lambda<Func<dynamic, decimal>>(castedValueExpression,
sourceParameterExpression);
}
以这种方式调用它会导致 InvalidCastException:
dynamic source = new ExpandoObject();
source.IntProp = 1;
decimal r = CreateLambdaCastExpression().Compile()(source);
如果我将 source.IntProp 设置为 1m,它可以工作(显然)
我在msdn 上读到过,ExpressionConvert 只对用户定义的类型执行隐式转换,所以这可能是解释。
知道如何对数字类型执行隐式转换吗?
【问题讨论】:
-
不确定我是否完全理解了这一点。但我相信
Expression.Convert遵循“实现方法是null”作为“expression.Type是引用类型”。它是object。所以如果是var sourcePropertyExpression = Expression.Dynamic( binder, typeof (int), sourceParameterExpression);可能会有帮助。
标签: c# dynamic expression-trees expandoobject