c# – Expression.Convert:’System.Int64’类型的对象无法转换为’System.Int32’类型
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了c# – Expression.Convert:’System.Int64’类型的对象无法转换为’System.Int32’类型,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2983字,纯文字阅读大概需要5分钟。
内容图文
我在昨天here问了一个关于从匿名对象中读取属性并将它们写入类的私有字段的问题.问题解决了.这是一个短篇小说:
我有一些json格式的数据.我将它们反序列化为ExpandoObject,并将它们作为IDictionary< string,object>传递给它们.方法.它工作正常,除了Int32属性.看来他们改成了Int64,在哪里?我不知道.
这是方法:
private Func<IDictionary<string, object>, dynamic> MakeCreator(
Type type, Expression ctor,
IEnumerable<PropertyToFieldMapper> maps) {
var list = new List<Expression>();
var vList = new List<ParameterExpression>();
// creating new target
var targetVariable = Expression.Variable(type, "targetVariable");
vList.Add(targetVariable);
list.Add(Expression.Assign(targetVariable, Expression.Convert(ctor, type)));
// accessing source
var sourceType = typeof(IDictionary<string, object>);
var sourceParameter = Expression.Parameter(sourceType, "sourceParameter");
// calling source ContainsKey(string) method
var containsKeyMethodInfo = sourceType.GetMethod("ContainsKey", new[] { typeof(string) });
var accessSourceIndexerProp = sourceType.GetProperty("Item");
var accessSourceIndexerInfo = accessSourceIndexerProp.GetGetMethod();
// itrate over writers and add their Call to block
var containsKeyMethodArgument = Expression.Variable(typeof(string), "containsKeyMethodArgument");
vList.Add(containsKeyMethodArgument);
foreach (var map in maps) {
list.Add(Expression.Assign(containsKeyMethodArgument, Expression.Constant(map.Property.Name)));
var containsKeyMethodCall = Expression.Call(sourceParameter, containsKeyMethodInfo,
new Expression[] { containsKeyMethodArgument });
// creating writer
var sourceValue = Expression.Call(sourceParameter, accessSourceIndexerInfo,
new Expression[] { containsKeyMethodArgument });
var setterInfo = map.Field.GetType().GetMethod("SetValue", new[] { typeof(object), typeof(object) });
var setterCall = Expression.Call(Expression.Constant(map.Field), setterInfo,
new Expression[] {
Expression.Convert(targetVariable, typeof(object)),
Expression.Convert(sourceValue, typeof(object))
});
Console.WriteLine(Expression.Lambda(setterCall));
list.Add(Expression.IfThen(containsKeyMethodCall, setterCall));
}
list.Add(targetVariable);
var block = Expression.Block(vList, list);
var lambda = Expression.Lambda<Func<IDictionary<string, object>, dynamic>>(
block, new[] { sourceParameter }
);
return lambda.Compile();
}
如果我们有这个
public class Person {
public int Age { get; set; }
public string Name { get; set; }
}
class,并使用此对象
var data = new { Name = "Amiry", Age = 20 };
要使用上面的方法初始化Person的实例,会发生以下错误:
Object of type ‘System.Int64’ cannot be converted to type ‘System.Int32’.
但是,如果我们将Age属性更改为:
public long Age { get; set; }
每件事看起来都很好,方法也很完美.我完全混淆了为什么会这样.你有什么主意吗?
解决方法:
所以你的输入词典包含很长(基于评论中的讨论).
最简单的解决方法是在SetValue之前添加Convert.ChangeType.
(传入sourceValue和Constant(map.Field.FieldType))
但是,这可能会产生意外后果 – 允许字符串 – > int转换.
另一种方法是添加您自己的ConvertType方法,您可以在其中决定如何转换类型.
内容总结
以上是互联网集市为您收集整理的c# – Expression.Convert:’System.Int64’类型的对象无法转换为’System.Int32’类型全部内容,希望文章能够帮你解决c# – Expression.Convert:’System.Int64’类型的对象无法转换为’System.Int32’类型所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。