如何使XML序列化与C#索引器(this [])很好地配合?

时间:2011-03-04 13:52:54

标签: c# xml-serialization

如何对以下属性进行XML序列化:

public class SomeCollection
{
    [Xml???]
    public SomeClass this[int i]
    {
        get { ... }
        set { ... }
    }
}

我尝试过使用XmlElementXmlArrayXmlArrayItem,但无济于事。

4 个答案:

答案 0 :(得分:2)

XmlSerializer不适用于索引器,您必须实施IXmlSerializable或(更好)使用代理属性来为您完成繁重的工作。

答案 1 :(得分:2)

根据Microsoft的说法,索引器无法使用XMLSerializer进行序列化

http://msdn.microsoft.com/en-us/library/182eeyhh.aspx

  

注意:XML序列化没有   转换方法,索引器,私有   字段或只读属性   (只读集合除外)。

答案 2 :(得分:1)

您无法序列化索引器属性。您可以做的最好的事情是暴露另一个属性(一个XML可序列化的属性),该属性与索引器使用的同一个集合相关联。

public class SomeCollection
{
    [XmlIgnore]
    public SomeClass this[int i]
    {
        get { ... }
        set { ... }
    }

    [XmlArray(ElementName="someClasses")]
    [XmlArrayItem(ElementName="someClass", Type=typeof(SomeClass))]
    public List<SomeClass> someClasses
    {
        get
        {
            // tie this into the same collection access by the indexer...
        }
        set
        {
            // tie this into the same collection access by the indexer...
        }
    }

}

答案 3 :(得分:1)

最简单的方法是实现IEnumerable和相应的Add方法。

例如,如果索引器使用List来存储列表,则以下代码应该完成这项工作:

将IEnumerable添加到正在实现的接口列表中。 初始化_list并实现索引器。

    private List<SomeClass> _list;

    ...

    public override void Add(SomeClass instance)
    {
        mInstances.Add(instance);
    }


    public IEnumerator<T> GetEnumerator()
    {
        foreach (SomeClass instance in _list)
        {
            yield return instance;
        }
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

请参阅XmlSerializer Class,其中包括以下注释:

  

XmlSerializer为实现IEnumerable或ICollection的类提供特殊处理。实现IEnumerable的类必须实现一个带有单个参数的公共Add方法。 Add方法的参数必须与从GetEnumerator返回的值的Current属性返回的类型相同,或者该类型的base之一。除了IEnumerable之外,实现ICollection(例如CollectionBase)的类必须具有一个公共Item索引属性(C#中的索引器),该属性采用整数,并且它必须具有integer类型的公共Count属性。 Add方法的参数必须与Item属性返回的类型相同,或者是该类型的基础之一。对于实现ICollection的类,要从序列化的Item属性中检索要序列化的值,而不是通过调用GetEnumerator。