C# 实现IEnumerator的类上的序列化

C# 实现IEnumerator的类上的序列化,c#,.net,xml-serialization,ienumerable,ienumerator,C#,.net,Xml Serialization,Ienumerable,Ienumerator,我已经写了一个程序,它将序列化和反序列化,它做得很好(我计划在子类上实现它,一旦我得到正确的工作在一个)。然而,当我决定使用Foreach迭代结果时,我遇到了麻烦 在这不起作用之后,我发现必须实现IEnumerator和IEnumerable接口,并将所需的方法添加到我的类中。所以我有,这确实允许我循环我的收藏 当我尝试将这两件事结合起来时,问题就开始了 序列化时,我最初遇到以下错误: 内部: {“TheResonlyRules.Army的类型不是预期的。请使用XmlInclude或SoapIn

我已经写了一个程序,它将序列化和反序列化,它做得很好(我计划在子类上实现它,一旦我得到正确的工作在一个)。然而,当我决定使用
Foreach
迭代结果时,我遇到了麻烦

在这不起作用之后,我发现必须实现
IEnumerator
IEnumerable
接口,并将所需的方法添加到我的类中。所以我有,这确实允许我循环我的收藏

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

序列化时,我最初遇到以下错误:

内部:
{“TheResonlyRules.Army的类型不是预期的。请使用XmlInclude或SoapInclude属性指定静态未知的类型。”}

我将
[xmlclude(typeof(Employee))]
添加到我的类中以防止此异常,但现在前两个根元素被称为
,而不是
。我不知道如何将它们更改回
[XmlRoot(“任意”)]
,因为某些原因没有效果

反序列化时,我收到此错误
{“XML文档(0,0)中存在错误”。}
内部:
{“缺少根元素”。}

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

我非常感谢您提供一些关于我遇到的这些问题的原因或解决方案的信息

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; }
    }
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Xml.Serialization;
使用System.Runtime.Serialization;
使用System.IO;
使用系统集合;
命名空间ThereIsOnlyRules
{
[xmlclude(类型(陆军))]
公共类ArmyList:IEnumerator,IEnumerable
{
//田地
私人名单(陆军),;
//性质
[XmlArray(“陆军类别”)]
公开名单军队
{
获取{返回{u军队;}
设置{u army=value;}
}
//公共方法
public-void-xml(ArmyListing-ArmyListing)
{
尝试
{
//armyListing.army.Add(陆军);
XmlSerializer serializer=新的XmlSerializer(typeof(ArmyListing));
//XmlSerializer serializer=新的XmlSerializer(typeof(ArmyList),新类型[]{typeof(ArmyList)});
TextWriter TextWriter=newstreamWriter(@“C:\Test\40k.xml”);
序列化(textWriter,ArmyList);
textWriter.Close();
}
捕获(例外情况除外){}
}
#区域IEnumerator/IEnumerable请求方法
[XmlIgnore]
私有整数位置=-1;
//枚举器&ienumerable
公共IEnumerator GetEnumerator()
{
返回(IEnumerator)这个;
}
//统计员
公共图书馆
{
位置++;
返回(位置<陆军计数);
}
//数不清
公共无效重置()
{
位置=0;
}
[XmlIgnore]
公共对象流
{
获取{返回军队[位置];}
}
//添加以防止异常
//要使XML可序列化,从IEnumerable继承的类型必须具有Add(System.Object)的实现
//在继承层次结构的所有级别。TheResonlyRules.ArmyList不实现Add(System.Object)。
公共无效添加(对象修复)
{ }
#端区
}
[可序列化]
公共类军队//:IEnumerator,IEnumerable
{
//田地
私人名单(单位类别),;
私有字符串_armyName;
//性质
[XmlArray(“单位类别”)]
公共列表单位类别
{
获取{return\u unitCategory;}
设置{u unitCategory=value;}
}
[XmlAttribute(“名称”)]
公共字符串ArmyName
{
获取{return\u armyName;}
设置{u armyName=value;}
}
//#区域IEnumerator/IEnumerable请求方法
//私有整数位置=-1;
////枚举器&ienumerable
//公共IEnumerator GetEnumerator()
//{
//返回(IEnumerator)这个;
//}
////统计员
//公共图书馆
//{
//位置++;
//返回(位置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;
    }

}
}
<?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>
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;
    }
}