JSON.NET - 如何为作为对象类型存储在数组/列表中的原始C#类型包括类型名称处理

Bai*_*ose 5 .net c# serialization json json.net

我正在使用Newtonsoft JSON.NET为我序列化/反序列化.但我有这个列表,其中的Object类型:

var list = new List<Object>() 
{ 
    "hi there", 
    1,
    2.33  
};
Run Code Online (Sandbox Code Playgroud)

当我使用TypeNameHandlingset 序列化时TypeNameHandling.All,我期望它也会$type为列表中的每个实例提供一个但似乎不是这样的情况.这是实际输出:

{
    "$type": "System.Collections.Generic.List`1[[System.Object, mscorlib]], mscorlib",
    "$values": [
        "hi there",
        1,
        2.33
    ]
}
Run Code Online (Sandbox Code Playgroud)

我需要这个原始类型具有特定的类型名称处理,因为如果我Int32在列表中添加一个值,并在反序列化后返回它,JSON.NET将其设置为Int64.这对我来说是一件大事,因为我试图调用一些方法并且这样做我需要比较参数,它们必须具有相同的类型.是否有一种方法或设置可以在JSON.NET中设置以实现我的需求?

我已经看过这篇文章,但它的作用是他试图改变默认行为并且总是返回Int32哪个不是我正在寻找的.

任何帮助,将不胜感激.谢谢

tda*_*t00 1

您可以为原始类型创建一个包装类,根据需要包含隐式运算符:

class TypeWrapper
{
    public object Value { get; set; }
    public string Type { get; set; }

    public static implicit operator TypeWrapper(long value)
    {
        return new TypeWrapper { Value = value, Type = typeof(long).FullName };
    }

    public static implicit operator long(TypeWrapper value)
    {
        return (long)value.Value;
    }

    public static implicit operator TypeWrapper(int value)
    {
        return new TypeWrapper { Value = value, Type = typeof(int).FullName };
    }

    public static implicit operator int(TypeWrapper value)
    {
        return (int)value.Value;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在序列化数据时您将拥有元素的类型:

var data = new List<TypeWrapper> { 1, 2L };
var json = Newtonsoft.Json.JsonConvert.SerializeObject(data);
Console.WriteLine(json);

// result: [{"Value":1,"Type":"System.Int32"},{"Value":2,"Type":"System.Int64"}]
Run Code Online (Sandbox Code Playgroud)