C# 反序列化';对象';(anyType)在XML文档中指定为特定的对象类型
我有一些使用ArrayList序列化数据的遗留代码,这会产生C# 反序列化';对象';(anyType)在XML文档中指定为特定的对象类型,c#,deserialization,C#,Deserialization,我有一些使用ArrayList序列化数据的遗留代码,这会产生的xml类型。它们都共享相同的数据类型,因此毫无意义,生成的代码乱七八糟 在反序列化时,除了在反序列化xml之前对其进行预清理外,是否有任何优雅的方法将此类数据强制放入列表中 基本上,我想把代码从 [Serializable()] public class SomeContainer { public ArrayList SomeDataList1 public ArrayList SomeDataList2 p
的xml类型。它们都共享相同的数据类型,因此毫无意义,生成的代码乱七八糟
在反序列化时,除了在反序列化xml之前对其进行预清理外,是否有任何优雅的方法将此类数据强制放入列表中
基本上,我想把代码从
[Serializable()]
public class SomeContainer
{
public ArrayList SomeDataList1
public ArrayList SomeDataList2
public ArrayList SomeDataList3
public ArrayList SomeDataList4
}
到
[Serializable()]
公共类容器
{
公共列表SomeDataList1
公共列表SomeDataList2
公共列表SomeDataList3
公共列表SomeDataList4
}
因此,我对ArrayList->List转换感兴趣,而不是容器。如果您用正确的XML属性标记类,您可以让您的
SomeContainer
类模仿ArrayList
反序列化XML的行为
您可能不在乎,但如果您还希望将类序列化为与ArrayList相同的格式,则需要让类实现IEnumerable
有关与ArrayList相同的完整序列化/反序列化,请参见下面的示例。如果需要,可以删除IEnumerable
实现,您将看到序列化更改。不过,使用“anyType”反序列化仍然可以在不实现IEnumerable
的情况下工作
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;
namespace SomeNamespace
{
[XmlType(nameof(SomeContainer))]
[XmlInclude(typeof(SomeType))]
public class SomeContainer : IEnumerable
{
[XmlArrayItem(typeof(SomeType))]
public List<SomeType> SomeDataList = new List<SomeType>();
public void Add(object o)
{
SomeDataList.Add(o as SomeType);
}
public int Count()
{
return SomeDataList.Count;
}
public IEnumerator GetEnumerator()
{
return SomeDataList.GetEnumerator();
}
}
public class SomeType
{
public string Name { get; set; } = "SomeName";
}
class Program
{
static void Main()
{
SomeContainer s1 = new SomeContainer();
s1.SomeDataList.Add(new SomeType());
string tempPath = "c:\\temp\\test.xml";
XmlSerializer serializer = new XmlSerializer(typeof(SomeContainer));
// serialize
using (StreamWriter sw = new StreamWriter(tempPath))
{
serializer.Serialize(sw, s1);
}
/* Produces the following XML:
<?xml version="1.0" encoding="utf-8"?>
<SomeContainer xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<anyType xsi:type="SomeType">
<Name>SomeName</Name>
</anyType>
</SomeContainer>
*/
// deserialize
SomeContainer s2;
using (StreamReader sr = new StreamReader(tempPath))
{
s2 = (SomeContainer)serializer.Deserialize(sr);
}
// check contents of s2 as you please
}
}
}
使用系统;
使用系统集合;
使用System.Collections.Generic;
使用System.IO;
使用System.Xml.Serialization;
名称空间名称空间
{
[XmlType(nameof(SomeContainer))]
[xmlclude(typeof(SomeType))]
公共类SomeContainer:IEnumerable
{
[XmlArrayItem(typeof(SomeType))]
public List SomeDataList=新列表();
公共无效添加(对象o)
{
添加(o作为SomeType);
}
公共整数计数()
{
返回SomeDataList.Count;
}
公共IEnumerator GetEnumerator()
{
返回SomeDataList.GetEnumerator();
}
}
公共类SomeType
{
公共字符串名称{get;set;}=“SomeName”;
}
班级计划
{
静态void Main()
{
SomeContainer s1=新的SomeContainer();
s1.SomeDataList.Add(newsometype());
字符串tempPath=“c:\\temp\\test.xml”;
XmlSerializer serializer=新的XmlSerializer(typeof(SomeContainer));
//连载
使用(StreamWriter sw=新StreamWriter(tempPath))
{
序列化器。序列化(sw,s1);
}
/*生成以下XML:
名字
*/
//反序列化
SomeContainer s2;
使用(StreamReader sr=新的StreamReader(tempPath))
{
s2=(SomeContainer)序列化程序。反序列化(sr);
}
//请检查s2的内容
}
}
}
(@Flydog57的评论是对的,我在键入时就这么说了。)如果你用正确的XML属性标记你的类,你可以让你的
SomeContainer
类模仿ArrayList
反序列化XML的行为
您可能不在乎,但如果您还希望将类序列化为与ArrayList相同的格式,则需要让类实现IEnumerable
有关与ArrayList相同的完整序列化/反序列化,请参见下面的示例。如果需要,可以删除IEnumerable
实现,您将看到序列化更改。不过,使用“anyType”反序列化仍然可以在不实现IEnumerable
的情况下工作
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;
namespace SomeNamespace
{
[XmlType(nameof(SomeContainer))]
[XmlInclude(typeof(SomeType))]
public class SomeContainer : IEnumerable
{
[XmlArrayItem(typeof(SomeType))]
public List<SomeType> SomeDataList = new List<SomeType>();
public void Add(object o)
{
SomeDataList.Add(o as SomeType);
}
public int Count()
{
return SomeDataList.Count;
}
public IEnumerator GetEnumerator()
{
return SomeDataList.GetEnumerator();
}
}
public class SomeType
{
public string Name { get; set; } = "SomeName";
}
class Program
{
static void Main()
{
SomeContainer s1 = new SomeContainer();
s1.SomeDataList.Add(new SomeType());
string tempPath = "c:\\temp\\test.xml";
XmlSerializer serializer = new XmlSerializer(typeof(SomeContainer));
// serialize
using (StreamWriter sw = new StreamWriter(tempPath))
{
serializer.Serialize(sw, s1);
}
/* Produces the following XML:
<?xml version="1.0" encoding="utf-8"?>
<SomeContainer xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<anyType xsi:type="SomeType">
<Name>SomeName</Name>
</anyType>
</SomeContainer>
*/
// deserialize
SomeContainer s2;
using (StreamReader sr = new StreamReader(tempPath))
{
s2 = (SomeContainer)serializer.Deserialize(sr);
}
// check contents of s2 as you please
}
}
}
使用系统;
使用系统集合;
使用System.Collections.Generic;
使用System.IO;
使用System.Xml.Serialization;
名称空间名称空间
{
[XmlType(nameof(SomeContainer))]
[xmlclude(typeof(SomeType))]
公共类SomeContainer:IEnumerable
{
[XmlArrayItem(typeof(SomeType))]
public List SomeDataList=新列表();
公共无效添加(对象o)
{
添加(o作为SomeType);
}
公共整数计数()
{
返回SomeDataList.Count;
}
公共IEnumerator GetEnumerator()
{
返回SomeDataList.GetEnumerator();
}
}
公共类SomeType
{
公共字符串名称{get;set;}=“SomeName”;
}
班级计划
{
静态void Main()
{
SomeContainer s1=新的SomeContainer();
s1.SomeDataList.Add(newsometype());
字符串tempPath=“c:\\temp\\test.xml”;
XmlSerializer serializer=新的XmlSerializer(typeof(SomeContainer));
//连载
使用(StreamWriter sw=新StreamWriter(tempPath))
{
序列化器。序列化(sw,s1);
}
/*生成以下XML:
名字
*/
//反序列化
SomeContainer s2;
使用(StreamReader sr=新的StreamReader(tempPath))
{
s2=(SomeContainer)序列化程序。反序列化(sr);
}
//请检查s2的内容
}
}
}
(@Flydog57的评论是对的,当我输入这段文字的时候,它就出现了。)关于我为肖恩·斯凯利的答案留下的评论
public class AnyList<T> : IEnumerable where T : class
{
List<T> holder = new List<T>();
public int Count()
{
return holder.Count;
}
public void Add(object objectToAdd)
{
T typedObjectToAdd = objectToAdd as T;
if (typedObjectToAdd != null)
{
holder.Add(typedObjectToAdd);
}
// If you can't guarantee the input data, should perhaps inform some data will be skipped.
}
public IEnumerator GetEnumerator()
{
return holder.GetEnumerator();
}
}
public class AnyList:IEnumerable其中T:class
{
列表持有者=新列表();
公共整数计数()
{
报税表持有人。计数;
}
public void Add(对象objectToAdd)
{
T typedObjectToAdd=对象toadd为T;
[Serializable()]
[XmlInclude(typeof(SomeType1))]
[XmlInclude(typeof(SomeType2))]
[XmlInclude(typeof(SomeType3))]
[XmlInclude(typeof(SomeType4))]
public class SomeContainer
{
public AnyList<SomeType1> SomeDataList1
public AnyList<SomeType2> SomeDataList2
public AnyList<SomeType3> SomeDataList3
public AnyList<SomeType4> SomeDataList4
}