你好,我有一个类的层次结构,在每个级别上都有一个char string[]={'c,'i','v','i','c'}; //size=5
// indexes: 0 1 2 3 4
字段和一个payload
字段,通过它们可以反序列化有效负载。我的问题是如何对诸如此类的东西反序列化你我不想弄乱层次结构。
我需要在每个步骤中做出决定:
id
PS 我尝试使用 public class Root
{
public int id { get; set; }
public Message msg { get; set; }
}
public abstract class Message
{
public int MessageID { get; set; }
}
public abstract class Com : Message
{
public int ComMsgId { get; set; }
}
public abstract class Game : Message
{
public int GameMsgID { get; set; }
}
public class Game1 : Game
{
public string Data { get; set; }
}
public class Com1 : Com
{
public bool IsDone { get; set; }
}
库,但它不适用于多级多态性。我还能做些其他事情吗?
答案 0 :(得分:1)
之所以没有更清洁的方法,是因为JSON不保存元数据信息,并且基于属性名称推断子类是一种非常复杂且占用大量资源的方法。
我通过在Message
类中创建一个虚拟属性来解决此问题,该属性指示要反序列化的类的类型,并在每个子类中为其分配一个值。例如在Com1
public override string ClassName => nameof(Com1)
然后实现由CustomSubClassConverter
继承的JsonConverter
,您可以在其中重写ReadJson属性以通过对ClassName属性应用切换大小写来转换JSON。
然后用Message
标记您的[JsonConverter(typeof(CustomSubClassConverter))]
类
如果您愿意,我将很高兴为您提供CustomSubClassConverter的代码。
更新
如果希望更容易适应新类的添加,还可以使用反射来获取子类,而不是使用switch / cases
答案 1 :(得分:0)
我已经通过将abstract
字段用作属性中的discriminator
来解决了该问题。此字段将在root
中定义,并且仅在leaf
中被覆盖- s。
然后我将单独实施有区别的工会。
为了能够在层次结构中的任何级别进行转换,我将用它们各自的叶子装饰中间抽象类:
例如,具有这样的类层次结构:
M
M1:M
,M2:M
[M11:M1
,M12:M1
]; [M21:M2
,M22:M2
]
叶子是M11,M12,M21,M22
的地方,我写了以下代码:
根
[JsonConverter(typeof(JsonSubTypes.JsonSubtypes), propType)]
[JsonSubTypes.JsonSubtypes.KnownSubType(typeof(M.M1.M11),Leaf.M11)]
[JsonSubTypes.JsonSubtypes.KnownSubType(typeof(M.M1.M12), Leaf.M12)]
[JsonSubTypes.JsonSubtypes.KnownSubType(typeof(M.M2.M21), Leaf.M21)]
[JsonSubTypes.JsonSubtypes.KnownSubType(typeof(M.M2.M22), Leaf.M22)]
public abstract partial class M
{
public static void Process(M message){
switch(message.MKind){
case M.Discriminator.M1 : M.M1.Process(message.AsM1);break;
case M.Discriminator.M2: M.M2.Process(message.AsM2);break;
}
}
[JsonIgnore]
public bool IsM1=>this.MKind==Discriminator.M1;
[JsonIgnore]
public bool IsM2=>this.MKind==Discriminator.M2;
[JsonIgnore]
public M1 AsM1=>this as M1;
[JsonIgnore]
public M2 AsM2=>this as M2;
private const string propType="$LeafKind";
public enum Discriminator {
M1=0,
M2=1
}
public enum Leaf {
M11=M1.Discriminator.M11*10,
M12=M1.Discriminator.M12*10,
M21=M2.Discriminator.M21*10,
M22=M2.Discriminator.M22*10
}
[JsonProperty(propType)]
public abstract Leaf LeafKind{get;}
protected abstract Discriminator MKind{get;}
public Discriminator Kind=>this.MKind;
public DateTime timestamp { get;}
}
摘要分支(级别2)
[JsonSubTypes.JsonSubtypes.KnownSubType(typeof(M.M1.M11),
M.Leaf.M11)]
[JsonSubTypes.JsonSubtypes.KnownSubType(typeof(M.M1.M12),M.Leaf.M12)]
public abstract partial class M1:M
{
public static void Process(M1 message){
switch(message.M1Kind){
case M1.Discriminator.M11 : M1.M11.Process(message.AsM11);break;
case M1.Discriminator.M12: M1.M12.Process(message.AsM12);break;
}
}
protected override M.Discriminator MKind => M.Discriminator.M1;
public new enum Discriminator {
M11=10,
M12=11
}
public new Discriminator Kind => this.M1Kind;
protected abstract Discriminator M1Kind { get; }
[JsonIgnore]
public bool IsM11=>this.M1Kind==M1.Discriminator.M11;
[JsonIgnore]
public bool IsM12=>this.M1Kind==M1.Discriminator.M12;
[JsonIgnore]
public M11 AsM11=>this as M11;
[JsonIgnore]
public M12 AsM12=>this as M12;
}
叶子
public class M11 : M1
{
public static void Process(M11 message){
Console.WriteLine(message.Value);
}
public bool Value{get;set;}
protected override Discriminator M1Kind => Discriminator.M11;
public override Leaf LeafKind => Leaf.M11;
}
要能够将类型为M11
的对象强制转换为M1
,我需要用M1
装饰KnownSubTypes
,但仅在{叶子。
PS 我还没有在此处添加所有discriminator
,但是您可以在Source Code
更新
我使用subtypes
代替了字符串enum
重新实现了层次结构。