C# 无法使用XML反序列化程序将XML反序列化到列表中
这是我上一个问题的后续内容C# 无法使用XML反序列化程序将XML反序列化到列表中,c#,deserialization,xmlserializer,C#,Deserialization,Xmlserializer,这是我上一个问题的后续内容 公共类MeterWalkOrder { 公共气象秩序() { 仪表=新列表(); } 公共字符串名称{get;set;} [XmlIgnore] 公共列表{get;set;} [XmlArrayItem(ElementName=“Meter”)] [XmlArray(ElementName=“米”)] 公共列表序列化参数 { 得到 { 返回仪表.Cast().ToList(); } 设置 { 仪表=新列表(值); } } } 公共接口流量计{ int MeterID{
公共类MeterWalkOrder
{
公共气象秩序()
{
仪表=新列表();
}
公共字符串名称{get;set;}
[XmlIgnore]
公共列表{get;set;}
[XmlArrayItem(ElementName=“Meter”)]
[XmlArray(ElementName=“米”)]
公共列表序列化参数
{
得到
{
返回仪表.Cast().ToList();
}
设置
{
仪表=新列表(值);
}
}
}
公共接口流量计{
int MeterID{get;set;}
}
公共类仪表:万用表{
公共int MeterID{get;set;}
公共字符串序列号{get;set;}
}
}
我正在使用下面的扩展方法将XML反序列化回我的对象(理想情况下,我希望扩展方法远离对象,但我对扩展方法不太熟悉,所以我现在就这样离开了)
公共静态类序列化扩展
{
公共静态T LoadFromXML(此字符串xmlString)
{
T返回值=默认值(T);
XmlSerializer serial=新的XmlSerializer(typeof(T));
StringReader=新的StringReader(xmlString);
对象结果=串行。反序列化(读取器);
if(result!=null&&result为T)
{
返回值=((T)结果);
}
reader.Close();
返回值;
}
……但是,当我给出下面的XML时
<?xml version="1.0"?>
<MeterWalkOrder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Name>Red Route</Name>
<Meters>
<Meter>
<MeterID>1</MeterID>
<SerialNumber>12345</SerialNumber>
</Meter>
<Meter>
<MeterID>2</MeterID>
<SerialNumber>SE</SerialNumber>
</Meter>
</Meters>
</MeterWalkOrder>
红色路线
1.
12345
2.
东南方
没有电表吗
有人知道是什么导致了这个问题吗?XML是有效的,SerializableMeters只是一个读取和写入米的属性,但由于在序列化中使用接口的已知问题,它将其转换为一个具体的类。问题是
XmlSerializer
反序列化引用类im的属性按以下方式执行IListIList
:
列表
替换为可观察集合
,并在集合更改时设置调试侦听器来验证这一点:
[XmlArrayItem(ElementName = "Meter")]
[XmlArray(ElementName = "Meters")]
public ObservableCollection<Meter> SerializableMeters
{
get
{
Debug.WriteLine("Returning proxy SerializableMeters");
var list = new ObservableCollection<Meter>(Meters.Cast<Meter>());
list.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(list_CollectionChanged);
return list;
}
set
{
Debug.WriteLine("Setting proxy SerializableMeters");
Meters = new List<IMeter>(value.Cast<IMeter>());
}
}
static void list_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
var collection = (IList<Meter>)sender;
Debug.WriteLine("Proxy collection changed to include : ");
foreach (var item in collection)
Debug.WriteLine(" " + item.ToString());
}
正如你所看到的,这个列表从来没有倒退过
幸运的是,有一个简单的替代方法。如果返回代理数组而不是代理列表,XmlSerializer
将分配数组本身,填充它,并通过setter进行设置——这正是您想要的
[XmlArrayItem(ElementName = "Meter")]
[XmlArray(ElementName = "Meters")]
public Meter [] SerializableMeters
{
get
{
return Meters.Cast<Meter>().ToArray();
}
set
{
Meters = new List<IMeter>(value.Cast<IMeter>());
}
}
[XmlArrayItem(ElementName=“Meter”)]
[XmlArray(ElementName=“米”)]
公用电表[]串行化电表
{
得到
{
返回仪表.Cast().ToArray();
}
设置
{
米=新列表(value.Cast());
}
}
后来
var meters = xml.LoadFromXML<MeterWalkOrder>();
Debug.Assert(meters.Meters.Count == 2); // No assert.
var meters=xml.LoadFromXML();
Debug.Assert(meters.meters.Count==2);//无断言。
为什么需要SerializableMeters?为什么不直接序列化Meters属性?我无法直接序列化它,因为它是一个不受支持的接口列表。我不想将其更改为使用具体类,因为我们总是将代码转换为接口而不是具体类
Returning proxy SerializableMeters
Returning proxy SerializableMeters
Returning proxy SerializableMeters
Returning proxy SerializableMeters
Proxy collection changed to include :
Meter: 1, 12345
Proxy collection changed to include :
Meter: 1, 12345
Meter: 2, SE
[XmlArrayItem(ElementName = "Meter")]
[XmlArray(ElementName = "Meters")]
public Meter [] SerializableMeters
{
get
{
return Meters.Cast<Meter>().ToArray();
}
set
{
Meters = new List<IMeter>(value.Cast<IMeter>());
}
}
var meters = xml.LoadFromXML<MeterWalkOrder>();
Debug.Assert(meters.Meters.Count == 2); // No assert.