尝试使用 DataContractSerializer 反序列化 int 列表,收到意外的 InvalidOperationException
Trying to deserialize list of ints using DataContractSerializer, received unexpected InvalidOperationException
期望:从 XML 文件读取整数列表到名为 itemPool 的列表;
结果:"InvalidOperationException: Failed to add type System.Collections.Generic.List`1[System.Int32] to known type collection. There already is a registered type for XML name http://schemas.microsoft.com/2003/10/Serialization/Arrays:ArrayOfint"
我必须遵循以下代码:
using System.Collections.Generic;
using System.Runtime.Serialization;
using Characters;
using Items;
[DataContract(Name ="Savefile", Namespace ="")]
public class Savefile
{
[DataMember(Name ="Characters")]
public List<Character> characters = new List<Character>();
[DataMember(Name = "ItemPool")]
public List<int> itemPool = new List<int>();
public void Initialize()
{
foreach (Character c in characters)
c.Initialize();
ItemPool.Load(itemPool.ToArray());
}
}
还有另一个 class 使用以下方法:
public static void LoadFromSavefile()
{
DataContractSerializer serializer = new DataContractSerializer(typeof(Savefile));
FileStream stream = new FileStream(Path.Combine(Application.dataPath, _savefilePath), FileMode.Open);
_currentSave = serializer.ReadObject(stream) as Savefile;
stream.Close();
}
以及上面 class 从中读取的以下 xml 文件。
<?xml version="1.0" encoding="utf-8"?>
<Savefile xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Characters>
<Character>
<... not relevant clutter.../>
</Character>
</Characters>
<ItemPool>
<value>1</value>
</ItemPool>
</Savefile>
使用 DataContractSerializer 编辑。
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Runtime.Serialization;
using System.Collections.Generic;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
namespace UnitTestProject1 {
[DataContract(Name = "Savefile", Namespace = "")]
public class Savefile {
[DataMember(Name = "Characters", Order = 0)]
public Characters Characters { get; private set; }
[DataMember(Name = "ItemPool", Order = 1)]
public Items ItemPool { get; private set; }
}
[CollectionDataContract(Name = "Characters", ItemName = "Character", Namespace = "")]
public class Characters : List<Character> {
}
public class Character {
public string Weapon { get; set; }
internal void Initialize() {
throw new NotImplementedException();
}
}
[CollectionDataContract(Name = "ItemPool", ItemName = "Item", Namespace = "")]
public class Items : List<int> {
public int value { get; set; }
}
[TestClass]
public class UnitTestSerialization {
[TestMethod]
public void TestMethod1() {
DataContractSerializer serializer = new DataContractSerializer(typeof(Savefile));
FileStream stream = new FileStream("SaveFile2.xml", FileMode.Open);
XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(stream, new XmlDictionaryReaderQuotas());
Savefile _currentSave = (Savefile)serializer.ReadObject(reader);
Assert.IsNotNull(_currentSave);
stream.Close();
}
}
}
xml 文件
<?xml version="1.0" encoding="utf-8"?>
<Savefile>
<Characters>
<Character>
<Weapon>Axe</Weapon>
</Character>
<Character>
<Weapon>Mace</Weapon>
</Character>
<Character>
</Character>
</Characters>
<ItemPool>
<Item>1</Item>
<Item>2</Item>
</ItemPool>
</Savefile>
期望:从 XML 文件读取整数列表到名为 itemPool 的列表;
结果:"InvalidOperationException: Failed to add type System.Collections.Generic.List`1[System.Int32] to known type collection. There already is a registered type for XML name http://schemas.microsoft.com/2003/10/Serialization/Arrays:ArrayOfint"
我必须遵循以下代码:
using System.Collections.Generic;
using System.Runtime.Serialization;
using Characters;
using Items;
[DataContract(Name ="Savefile", Namespace ="")]
public class Savefile
{
[DataMember(Name ="Characters")]
public List<Character> characters = new List<Character>();
[DataMember(Name = "ItemPool")]
public List<int> itemPool = new List<int>();
public void Initialize()
{
foreach (Character c in characters)
c.Initialize();
ItemPool.Load(itemPool.ToArray());
}
}
还有另一个 class 使用以下方法:
public static void LoadFromSavefile()
{
DataContractSerializer serializer = new DataContractSerializer(typeof(Savefile));
FileStream stream = new FileStream(Path.Combine(Application.dataPath, _savefilePath), FileMode.Open);
_currentSave = serializer.ReadObject(stream) as Savefile;
stream.Close();
}
以及上面 class 从中读取的以下 xml 文件。
<?xml version="1.0" encoding="utf-8"?>
<Savefile xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Characters>
<Character>
<... not relevant clutter.../>
</Character>
</Characters>
<ItemPool>
<value>1</value>
</ItemPool>
</Savefile>
使用 DataContractSerializer 编辑。
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Runtime.Serialization;
using System.Collections.Generic;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
namespace UnitTestProject1 {
[DataContract(Name = "Savefile", Namespace = "")]
public class Savefile {
[DataMember(Name = "Characters", Order = 0)]
public Characters Characters { get; private set; }
[DataMember(Name = "ItemPool", Order = 1)]
public Items ItemPool { get; private set; }
}
[CollectionDataContract(Name = "Characters", ItemName = "Character", Namespace = "")]
public class Characters : List<Character> {
}
public class Character {
public string Weapon { get; set; }
internal void Initialize() {
throw new NotImplementedException();
}
}
[CollectionDataContract(Name = "ItemPool", ItemName = "Item", Namespace = "")]
public class Items : List<int> {
public int value { get; set; }
}
[TestClass]
public class UnitTestSerialization {
[TestMethod]
public void TestMethod1() {
DataContractSerializer serializer = new DataContractSerializer(typeof(Savefile));
FileStream stream = new FileStream("SaveFile2.xml", FileMode.Open);
XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(stream, new XmlDictionaryReaderQuotas());
Savefile _currentSave = (Savefile)serializer.ReadObject(reader);
Assert.IsNotNull(_currentSave);
stream.Close();
}
}
}
xml 文件
<?xml version="1.0" encoding="utf-8"?>
<Savefile>
<Characters>
<Character>
<Weapon>Axe</Weapon>
</Character>
<Character>
<Weapon>Mace</Weapon>
</Character>
<Character>
</Character>
</Characters>
<ItemPool>
<Item>1</Item>
<Item>2</Item>
</ItemPool>
</Savefile>