C# 当对象从列表继承时序列化对象 [DataContract] 公开甲级:名单 { [数据成员] 公共双测试{get;set;} } [数据合同] 公共B级 { [数据成员] 公共双测试b{get;set;} }

C# 当对象从列表继承时序列化对象 [DataContract] 公开甲级:名单 { [数据成员] 公共双测试{get;set;} } [数据合同] 公共B级 { [数据成员] 公共双测试b{get;set;} },c#,json,inheritance,serialization,C#,Json,Inheritance,Serialization,使用上述模型,我尝试序列化以下对象: [DataContract] public class A : List<B> { [DataMember] public double TestA { get; set; } } [DataContract] public class B { [DataMember] public double TestB { get; set; } } List(XML),但我想知道是否没有通过设置一些JSON序列化选项来

使用上述模型,我尝试序列化以下对象:

[DataContract]
public class A : List<B>
{
    [DataMember]
    public double TestA { get; set; }
}

[DataContract]
public class B
{
    [DataMember]
    public double TestB { get; set; }
}
List(XML),但我想知道是否没有通过设置一些JSON序列化选项来包含这些值的选项


注意:在类
a
中创建属性
列表
而不是继承对我来说是没有选择的。

根据上面的评论(谢谢!)有两种方法可以获得正确的结果:

  • 实现自定义的
    JsonConverter
    ()
  • Workarround:在类中创建一个属性,该属性返回项()
无论如何,从
列表继承
很少是一个好的解决方案()

我已经用Workaround试过了:

List<A> list = new List<A>()
{
    new A() { TestA = 1 },
    new A() { TestA = 3 }
};

json = JsonConvert.SerializeObject(list);
//json: [[],[]]
[JsonObject(MemberSerialization=MemberSerialization.OptIn)]
公开甲级:名单
{
[JsonProperty]
公共双测试{get;set;}
[JsonProperty]
公共B[]项目
{
得到
{
返回此.ToArray();
}
设置
{
if(值!=null)
此.AddRange(值);
}
}
}
公共B级
{
公共双测试b{get;set;}
}

这适用于序列化和反序列化。重要提示:
必须是
B
数组
,并且没有
列表
。否则反序列化对
项不起作用

出于好奇,为什么要创建从列表派生的类?很少有人需要这样做。创建一个同时包含list和double的类比扩展list更有意义。请参阅所谓的问题“”和Eric Lippert的非常好的答案。结果表明,当应用
[DataContact]
时,Json.NET不支持将集合序列化为对象。请看。@dbc有趣的答案,我注意到您说过,如果您的类实现了
ICollection
,它将能够添加成员,但列表确实实现了这一点,这是一个bug?还有第二个问题,即JSON有两种不同类型的容器,数组:
[1,2,…,n]
和对象:
{“prop1”:1,,“propN”:n}
。如果Json.NET将类型序列化为对象,则会丢失项。如果作为数组,则会丢失属性。你需要一个特殊的转换器来实现这两个功能。请参阅或。@ScottChamberlain我需要它来在ListView()中的Xamarin表单中进行复杂分组。我不明白为什么Xamarin希望它以这种“继承方式”而不是属性
列表
(像往常一样)。
[JsonObject(MemberSerialization = MemberSerialization.OptIn)]
public class A : List<B>
{
    [JsonProperty]
    public double TestA { get; set; }

    [JsonProperty]
    public B[] Items
    {
        get
        {
            return this.ToArray();
        }
        set
        {
            if (value != null)
                this.AddRange(value);
        }
    }
}

public class B
{
    public double TestB { get; set; }
}