首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >JsonSerializer.Deserialize:将对象反序列化为其实际类型

JsonSerializer.Deserialize:将对象反序列化为其实际类型
EN

Stack Overflow用户
提问于 2022-10-31 08:16:19
回答 2查看 72关注 0票数 0

我正在将JSON列表反序列化为object[],并期望得到一个对象数组。不过,我希望反序列化为更具体的类型。是否有办法做到这一点,可能在序列化时提供确切的类型?不幸的是,我无法在代码中比object[]更具体..。

代码语言:javascript
运行
复制
using System.Text.Json;

namespace Tests.DeSerialize;

class Program
{
    public static void Main(string[] args)
    {
        object[] objs = new object[]{
            42,
            "foobar",
            false,
            new Example {
                Name = "example",
            }
        };
        foreach (var obj in objs)
        {
            Console.WriteLine(obj.GetType().Name);
        }

        var serialized = JsonSerializer.Serialize(objs);
        Console.WriteLine();
        Console.WriteLine(serialized);
        Console.WriteLine();

        object[] deSerializedObjs = JsonSerializer.Deserialize<object[]>(serialized);
        foreach (var obj in deSerializedObjs)
        {
            Console.WriteLine(obj.GetType().FullName);
        }
    }
}

public class Example
{
    public string Name { get; set; }

    public override string ToString() => $"{GetType().Name}(\"{Name}\")";
}

输出:

代码语言:javascript
运行
复制
Int32
String
Boolean
Example

[42,"foobar",false,{"Name":"example"}]

System.Text.Json.JsonElement
System.Text.Json.JsonElement
System.Text.Json.JsonElement
System.Text.Json.JsonElement

是否有办法将确切的类型编码成序列化的文本?

EN

回答 2

Stack Overflow用户

发布于 2022-10-31 12:53:42

是。您只需要为正在序列化/反序列化的对象创建一个C#类。

代码语言:javascript
运行
复制
// you can use more meaningful names for the classes/variables
public class Object
{
   public int MyInt { get; set; }
   public string MyStr { get; set; }
   public bool MyBool { get; set; }
   public Example Example{ get; set; }
}

public class Example
{
   public string Name { get; set; }
   // other variables that might be in the Example object
}

序列化对象应该是相同的,但是在反序列化时,您需要做一些小的更改:

代码语言:javascript
运行
复制
// use the public class name and if expecting an array use a collection such as List
var deSerializedObjs = JsonSerializer.Deserialize<List<Object>>(serialized);
票数 0
EN

Stack Overflow用户

发布于 2022-11-16 05:20:14

这里有一个快速而肮脏的解决方案。您可以使用它作为一个原型来进一步开发您自己的作品。非原始类型的类型名是通过匿名类和硬编码的属性名添加的,后者是脏的部分。

代码语言:javascript
运行
复制
using System.Text.Json;

namespace Tests.DeSerialize;

class Program
{
    public static void Main(string[] args)
    {

        object[] objs = new object[]{
            42,
            "foobar",
            false,
            new {
                Type = "Tests.DeSerialize.Example",
                Value = new Example{
                    Name = "example"
                }
            }
        };

        foreach (var obj in objs)
        {
            Console.WriteLine(obj.GetType().Name);
        }

        var serialized = JsonSerializer.Serialize(objs);
        Console.WriteLine();
        Console.WriteLine(serialized);
        Console.WriteLine();

        var deSerializedObjs = JsonSerializer.Deserialize<JsonElement[]>(serialized);
        foreach (var obj in deSerializedObjs)
        {
            Console.WriteLine(obj.MyDeserialize().GetType().FullName);
        }
    }
}

public static class JsonElementExtension
{
    public static Object MyDeserialize(this JsonElement jsonElement)
    {
        switch (jsonElement.ValueKind)
        {
            case JsonValueKind.String:
                return jsonElement.Deserialize(typeof(string));

            case JsonValueKind.Number:
                return jsonElement.Deserialize(typeof(int));

            case JsonValueKind.False:
            case JsonValueKind.True:
                return jsonElement.Deserialize(typeof(bool));

            case JsonValueKind.Array:
                return jsonElement.Deserialize(typeof(Array));

            case JsonValueKind.Object:

                return jsonElement.GetProperty("Value").Deserialize(Type.GetType(jsonElement.GetProperty("Type").GetString()));

            default:
                return jsonElement.Deserialize(typeof(object));
        }
    }
}

输出:

代码语言:javascript
运行
复制
Int32
String
Boolean
<>f__AnonymousType0`2

[42,"foobar",false,{"Type":"Tests.DeSerialize.Example","Value":{"Name":"example"}}]

System.Int32
System.String
System.Boolean
Tests.DeSerialize.Example
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74260428

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档