0

我收到一条 json 消息,其中包含一个名为的字段"item",可以反序列化为类 foo 或类 bar。如何在 C# 中实现这一点?

我假设是这样的:

public class FooOrBar 
{
     // Only one of the two will get populated.
     public Foo foo { get; set; }
     public Bar bar { get; set; }
     bool is_foo;
}

[JsonProperty("item")]
[JsonConverter(typeof(CustomConverter))]
public FooOrBar Item { get; set; }

如何为这种情况实现自定义转换器?

有没有更简单的解决方案?

4

1 回答 1

1

我不确定你的代码是如何Foo确定Bar的,但现在让我们假设你有一个这样的 JSON 结构:

var json = @"
{
  isFoo: true,
  item: {}
}";

在这种情况下FooBar由 确定isFoo

FooOrBar类可能是主观的。我不会这样定义类,而是使用多态性:

interface IItem
{
    bool IsFoo { get; }
}

class Foo : IItem
{
    public bool IsFoo => true;
}

class Bar : IItem
{
    public bool IsFoo => false;
}

[JsonConverter(typeof(CustomJsonConverter))]
class MyClass
{
    public IItem Item { get; set; }
}

我设置CustomJsonConverterMyClass因为我有 JSON 结构。我需要使用父对象中可用的信息item来确定Foo或者Bar我必须设置JsonConverterItem属性的声明类型。如果您使用item属性中可用的信息,您可以将转换器移至Item属性。

现在CustomJsonConverter像这样实现:

class CustomJsonConverter : JsonConverter
{
    public override bool CanConvert(Type objectType) => true;

    public override object ReadJson(JsonReader reader, Type objectType, 
        object existingValue, JsonSerializer serializer)
    {
        var token = JToken.ReadFrom(reader);
        if (token.Type == JTokenType.Null)
        {
            return null;
        }

        // Create an instance of MyClass, and set property as per "isFoo".
        var obj = new MyClass();        

        if (token["isFoo"].Value<bool>())
        {
            obj.Item = new Foo();
        }
        else
        {
            obj.Item = new Bar();
        }

        // Populate properties
        serializer.Populate(token.CreateReader(), obj);
        return obj;
    }

    public override void WriteJson(JsonWriter writer, object value, 
        JsonSerializer serializer)
    {
        throw new NotSupportedException();
    }
}
于 2020-04-12T06:01:07.903 回答