gpt4 book ai didi

c# - 表达式.Convert : Object of type 'System.Int64' cannot be converted to type 'System.Int32'

转载 作者:太空狗 更新时间:2023-10-30 01:06:02 34 4
gpt4 key购买 nike

我昨天问了一个问题here关于从匿名对象读取属性并将它们写入类的私有(private)字段。问题解决了。这是一个小故事:

我有一些 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; }
}

类,并使用这个对象

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; }

一切看起来都很好,方法也很完美。我完全不明白为什么会这样。你有什么想法吗?

最佳答案

表述正确。问题是 Json.NET。它将所有数值(在匿名转换中)转换为 Int64。所以,我只需要一个自定义转换器:

public class JsonIntegerConverter : JsonConverter {

public override bool CanConvert(Type objectType) {
return objectType == typeof(IDictionary<string, object>);
}

public override bool CanWrite {
get { return false; }
}

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) {
var result = new Dictionary<string, object>();
reader.Read();

while (reader.TokenType == JsonToken.PropertyName) {
var propertyName = (string)reader.Value;
reader.Read();
object value;
if (reader.TokenType == JsonToken.Integer) {
var temp = Convert.ToInt64(reader.Value);
if (temp <= Byte.MaxValue && temp >= Byte.MinValue)
value = Convert.ToByte(reader.Value);
else if (temp >= Int16.MinValue && temp <= Int16.MaxValue)
value = Convert.ToInt16(reader.Value);
else if (temp >= Int32.MinValue && temp <= Int32.MaxValue)
value = Convert.ToInt32(reader.Value);
else
value = temp;
} else
value = serializer.Deserialize(reader);
result.Add(propertyName, value);
reader.Read();
}

return result;
}

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) {
throw new NotSupportedException();
}
}

这是一个具体的实现,绝对可以实现得更加扩展和有用。但它只是解决了我目前的问题。

关于c# - 表达式.Convert : Object of type 'System.Int64' cannot be converted to type 'System.Int32' ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16683784/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com