如何将一个项目反序列化为不同的类型? (Newtonsoft、C#、.NET)
How to deserialize an item into different types? (Newtonsoft, C#, .NET)
我收到一条 json 消息,其中包含一个名为 "item"
的字段,可以将其反序列化为 class foo 或 class 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; }
如何为这种情况实现自定义转换器?
有没有更简单的解决方案?
我不确定 Foo
或 Bar
是如何在您的代码中确定的,但现在让我们假设您有一个像这样的 JSON 结构:
var json = @"
{
isFoo: true,
item: {}
}";
在这种情况下 Foo
或 Bar
由 isFoo
决定。
FooOrBar
class 可能是主观的。我不会那样定义 class,而是使用多态性:
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; }
}
我将 CustomJsonConverter
设置为 MyClass
因为我有 JSON 结构。我需要使用 item
的父对象中可用的信息来确定 Foo
或 Bar
,因此我必须将 JsonConverter
设置为 Item
的声明类型 属性。如果您使用 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();
}
}
我收到一条 json 消息,其中包含一个名为 "item"
的字段,可以将其反序列化为 class foo 或 class 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; }
如何为这种情况实现自定义转换器?
有没有更简单的解决方案?
我不确定 Foo
或 Bar
是如何在您的代码中确定的,但现在让我们假设您有一个像这样的 JSON 结构:
var json = @"
{
isFoo: true,
item: {}
}";
在这种情况下 Foo
或 Bar
由 isFoo
决定。
FooOrBar
class 可能是主观的。我不会那样定义 class,而是使用多态性:
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; }
}
我将 CustomJsonConverter
设置为 MyClass
因为我有 JSON 结构。我需要使用 item
的父对象中可用的信息来确定 Foo
或 Bar
,因此我必须将 JsonConverter
设置为 Item
的声明类型 属性。如果您使用 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();
}
}