标签:dynamic expandoobject c expression-trees
我有一个带有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仅对用户定义的类型执行隐式转换,因此可能就是解释.
关于如何对数字类型执行隐式强制转换的任何想法吗?
解决方法:
更改这些行:
// CSharpBinderFlags.ConvertExplicit: explicit cast
// (will convert double to decimal)
// CSharpBinderFlags.None: implicit cast
// (will convert int to decimal, won't convert double to decimal)
var convert = Binder.Convert(CSharpBinderFlags.ConvertExplicit, typeof(decimal), typeof(ExpressionTreeUtils));
// (decimal) source;
var castedValueExpression = Expression.Dynamic(
convert, typeof(decimal), sourcePropertyExpression);
请注意有关隐式/显式强制转换的注释.
(因此唯一改变的是var castedValueExpression的构建方式)
ideone带有完整示例.
标签:dynamic,expandoobject,c,expression-trees 来源: https://codeday.me/bug/20191119/2039475.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。