gpt4 book ai didi

c# - 对实现 IEnumerator 的类进行序列化

转载 作者:太空宇宙 更新时间:2023-11-03 14:06:03 25 4
gpt4 key购买 nike

我已经编写了一个程序来序列化和反序列化,它做得很好(我计划在子类上正常工作后在子类上实现它)。然而,当我决定使用 Foreach 遍历结果时,我遇到了麻烦。 .

在这不起作用之后,我发现必须实现 IEnumeratorIEnumerable接口(interface)并将所需的方法添加到我的类中。所以我有,这确实让我可以循环浏览我的收藏。

当我尝试将这两件事结合起来时,问题就开始了......

序列化时我最初得到这个错误:

内部: {"The type ThereIsOnlyRules.Army was not expected. Use the XmlInclude or SoapInclude attribute to specify types that are not known statically."}

我添加了 [XmlInclude(typeof(Employee))]到我的类(class)来防止这个异常,但现在前两个根元素被称为 <ArrayofAnyType><AnyType>而不是 <ArmyListing><Army> .我不知道如何将它们改回 [XmlRoot("whatever")]由于某种原因没有效果。

反序列化时出现此错误 {"There is an error in XML document (0, 0)."}内部:{"Root element is missing."}

我已经搜索过 - 但似乎可以通过多种不同方式生成此错误。我还没有找到适用于我的代码的任何解决方案(据我所知)。

如果能提供有关我遇到的这些问题的原因或解决方案的信息,我将不胜感激!

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.Runtime.Serialization;
using System.IO;
using System.Collections;

namespace ThereIsOnlyRules
{
[XmlInclude(typeof(Army))]
public class ArmyListing : IEnumerator, IEnumerable
{

// Fields
private List<Army> _army;

// Properties
[XmlArray("army-category")]
public List<Army> Army
{
get { return _army; }
set { _army = value; }
}

// Public Methods
public void SerializeToXML(ArmyListing armyListing)
{
try
{
//armyListing.army.Add(army);

XmlSerializer serializer = new XmlSerializer(typeof(ArmyListing));
//XmlSerializer serializer = new XmlSerializer(typeof(ArmyListing), new Type[] { typeof(ArmyListing) });
TextWriter textWriter = new StreamWriter(@"C:\Test\40k.xml");
serializer.Serialize(textWriter, armyListing);
textWriter.Close();
}
catch (Exception ex) { }
}

#region IEnumerator/IEnumerable req methods
[XmlIgnore]
private int position = -1;
//enumerator & ienumerable
public IEnumerator GetEnumerator()
{
return (IEnumerator)this;
}

//enumerator
public bool MoveNext()
{
position++;
return (position < Army.Count);
}

//ienumerable
public void Reset()
{
position = 0;
}
[XmlIgnore]
public object Current
{
get { return Army[position]; }
}

// Added to prevent Exception
// To be XML serializable, types which inherit from IEnumerable must have an implementation of Add(System.Object)
//at all levels of their inheritance hierarchy. ThereIsOnlyRules.ArmyListing does not implement Add(System.Object).
public void Add(Object fix)
{ }
#endregion
}

[Serializable]
public class Army// : IEnumerator, IEnumerable
{
// Fields
private List<UnitCategory> _unitCategory;
private string _armyName;

// Properties
[XmlArray("unit-category")]
public List<UnitCategory> UnitCategory
{
get { return _unitCategory; }
set { _unitCategory = value; }
}

[XmlAttribute("name")]
public string ArmyName
{
get { return _armyName; }
set { _armyName = value; }
}

//#region IEnumerator/IEnumerable req methods
//private int position = -1;
////enumerator & ienumerable
//public IEnumerator GetEnumerator()
//{
// return (IEnumerator)this;
//}

////enumerator
//public bool MoveNext()
//{
// position++;
// return (position < UnitCategory.Count);
//}

////ienumerable
//public void Reset()
//{
// position = 0;
//}
//public object Current
//{
// get { return UnitCategory[position]; }
//}
//public void Add(Object Army)
//{ }
//#endregion
}

[Serializable]
public class UnitCategory// : IEnumerator, IEnumerable
{
// Fields
private List<UnitType> _unitType;
private string _unitCategoryName;

// Properties
[XmlArray("unit-type")]
public List<UnitType> UnitType
{
get { return _unitType; }
set { _unitType = value; }
}

[XmlAttribute("name")]
public string UnitCategoryName
{
get { return _unitCategoryName; }
set { _unitCategoryName = value; }
}

//#region IEnumerator/IEnumerable req methods
//private int position = -1;
////enumerator & ienumerable
//public IEnumerator GetEnumerator()
//{
// return (IEnumerator)this;
//}

////enumerator
//public bool MoveNext()
//{
// position++;
// return (position < UnitType.Count);
//}

////ienumerable
//public void Reset()
//{
// position = 0;
//}
//public object Current
//{
// get { return UnitType[position]; }
//}
//public void Add(Object Army)
//{ }
//#endregion
}

[Serializable]
public class UnitType// : IEnumerator, IEnumerable
{
// Fields
private List<Unit> _unit;
private string _unitTypeName;

//Properties
[XmlArray("unit")]
public List<Unit> Unit
{
get { return _unit; }
set { _unit = value; }
}

[XmlAttribute("name")]
public string UnitTypeName
{
get { return _unitTypeName; }
set { _unitTypeName = value; }
}

//#region IEnumerator/IEnumerable req methods
//private int position = -1;

////enumerator & ienumerable
//public IEnumerator GetEnumerator()
//{
// return (IEnumerator)this;
//}

////enumerator
//public bool MoveNext()
//{
// position++;
// return (position < Unit.Count);
//}

////ienumerable
//public void Reset()
//{
// position = 0;
//}
//public object Current
//{
// get { return Unit[position]; }
//}

//public void Add(Object Army)
//{ }
//#endregion
}

[Serializable]
public class Unit
{
// Fields
private string _unitName;
private string _composition;
private string _weaponSkill;
private string _ballisticSkill;
private string _strength;
private string _initiative;
private string _toughness;
private string _wounds;
private string _attacks;
private string _leadership;
private string _savingThrow;
private string _specialRules;
private string _dedicatedTransport;
private string _options;
private string _armour;
private string _weapons;

// Properties
[XmlAttribute("name")]
public string UnitName
{
get { return _unitName; }
set { _unitName = value; }
}

[XmlAttribute("composition")]
public string Composition
{
get { return _composition; }
set { _composition = value; }
}

[XmlAttribute("weapon-skill")]
public string WeaponSkill
{
get { return _weaponSkill; }
set { _weaponSkill = value; }
}

[XmlAttribute("ballistic-skill")]
public string BallisticSkill
{
get { return _ballisticSkill; }
set { _ballisticSkill = value; }
}

[XmlAttribute("strength")]
public string Strength
{
get { return _strength; }
set { _strength = value; }
}

[XmlAttribute("toughness")]
public string Toughness
{
get { return _toughness; }
set { _toughness = value; }
}

[XmlAttribute("wounds")]
public string Wounds
{
get { return _wounds; }
set { _wounds = value; }
}

[XmlAttribute("initiative")]
public string Initiative
{
get { return _initiative; }
set { _initiative = value; }
}

[XmlAttribute("attacks")]
public string Attacks
{
get { return _attacks; }
set { _attacks = value; }
}

[XmlAttribute("leadership")]
public string Leadership
{
get { return _leadership; }
set { _leadership = value; }
}

[XmlAttribute("saving-throw")]
public string SaveThrow
{
get { return _savingThrow; }
set { _savingThrow = value; }
}

[XmlAttribute("armour")]
public string Armour
{
get { return _armour; }
set { _armour = value; }
}

[XmlAttribute("weapons")]
public string Weapons
{
get { return _weapons; }
set { _weapons = value; }
}

[XmlAttribute("special-rules")]
public string SpecialRules
{
get { return _specialRules; }
set { _specialRules = value; }
}

[XmlAttribute("dedicated-transport")]
public string DedicatedTransport
{
get { return _dedicatedTransport; }
set { _dedicatedTransport = value; }
}

[XmlAttribute("options")]
public string Options
{
get { return _options; }
set { _options = value; }
}
}
}

表单

using System;
using System.Windows.Forms;
using System.Collections.Generic;
using System.Xml.Serialization;
using System.IO;

namespace ThereIsOnlyRules
{
public partial class Form1 : Form
{
ArmyListing armyListing;
ArmyListing XmlListing = new ArmyListing();

public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
SerializeArmyListings();
}

public static void SerializeArmyListings()
{
UnitCategory troopsCategory = new UnitCategory
{
UnitCategoryName = "Troops",
UnitType = new List<UnitType>
{
new UnitType
{
UnitTypeName = "Infantry",
Unit = new List<Unit>
{
new Unit
{
Armour = "Chitin",
Attacks = "3",
BallisticSkill = "100",
Composition = "20",
DedicatedTransport = "No",
Initiative = "3",
Leadership = "5",
Options = "8",
SaveThrow = "6+",
SpecialRules = "None",
Strength = "3",
Toughness = "4",
UnitName = "Hornmagant",
Weapons = "Many",
WeaponSkill = "3",
Wounds = "1"
}
}
}
}
};

Army army = new Army
{
ArmyName = "Tyranid",
UnitCategory = new List<UnitCategory>
{
troopsCategory
}
};

ArmyListing armyListing = new ArmyListing
{
Army = new List<Army>
{
army
}
};

armyListing.SerializeToXML(armyListing);// SerializeToXml(armyListing);
}

public ArmyListing DeserializeXml()
{

string path = @"C:\Test\40k.xml";

XmlSerializer serializer = new XmlSerializer(typeof(ArmyListing));
//XmlSerializer serializer = new XmlSerializer(typeof(ArmyListing), new Type[] { typeof(ArmyListing) });


StreamReader reader = new StreamReader(path);

XmlListing = (ArmyListing)serializer.Deserialize(reader);
reader.Close();

return XmlListing;

}

private void button2_Click(object sender, EventArgs e)
{
DeserializeXml();

////test
//foreach (var list in armyListing)
//{
// listBox1.DataSource = list;
//}

int xmlcount = XmlListing.Army.Count;
}

}
}

最佳答案

我发现删除了 IEnumerator、IEnumerable 的实现,那么您就不必使用 XmlInclude。

下面是可以反序列化的输出 xml。

<?xml version="1.0" encoding="utf-8"?>
<ArmyListing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<army-category>
<Army name="Tyranid">
<unit-category>
<UnitCategory name="Troops">
<unit-type>
<UnitType name="Infantry">
<unit>
<Unit name="Hornmagant" composition="20" weapon-skill="3" ballistic-skill="100" strength="3" toughness="4" wounds="1" initiative="3" attacks="3" leadership="5" saving-throw="6+" armour="Chitin" weapons="Many" special-rules="None" dedicated-transport="No" options="8" />
</unit>
</UnitType>
</unit-type>
</UnitCategory>
</unit-category>
</Army>
</army-category>
</ArmyListing>

编辑:我想如果类实现 IEnumerable 和 IEnumerator。 XmlSerialer 将使用它来枚举。 object Current {} 属性导致类型丢失。所以 Anytype 显示。

我的建议是实现 IEnumerable、IEnumerator以下是我的测试代码:

public class ArmyListing :  IEnumerable<Army>, IEnumerator<Army>
{

// Fields
private List<Army> _army;

// Properties
[XmlArray("army-category")]
public List<Army> Army
{
get { return _army; }
set { _army = value; }
}

// Public Methods
public void SerializeToXML(ArmyListing armyListing)
{
try
{
//armyListing.army.Add(army);

XmlSerializer serializer = new XmlSerializer(typeof(ArmyListing));
//XmlSerializer serializer = new XmlSerializer(typeof(ArmyListing), new Type[] { typeof(ArmyListing) });
TextWriter textWriter = new StreamWriter(@"C:\Temp\40k.xml");
serializer.Serialize(textWriter, armyListing);
textWriter.Close();
}
catch (Exception ex) { }
}

#region IEnumerator/IEnumerable req methods
[XmlIgnore]
private int position = -1;


// Added to prevent Exception
// To be XML serializable, types which inherit from IEnumerable must have an implementation of Add(System.Object)
//at all levels of their inheritance hierarchy. ThereIsOnlyRules.ArmyListing does not implement Add(System.Object).

public void Add(Army fix)
{
if (_army == null)
_army = new List<Army>();

_army.Add(fix);
}
#endregion

public IEnumerator<Army> GetEnumerator()
{
return this;
}

IEnumerator IEnumerable.GetEnumerator()
{
return this;
}

[XmlIgnore]
public Army Current
{
get { return _army[position]; }

}

public void Dispose()
{

}

[XmlIgnore]
object IEnumerator.Current
{
get { return _army[position]; }
}

public bool MoveNext()
{
position++;
return (position < Army.Count);
}

public void Reset()
{
position = 0;
}
}

关于c# - 对实现 IEnumerator 的类进行序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9285863/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com