Как заставить сериализацию XML работать с индексаторами C # (this [])? - PullRequest
0 голосов
/ 04 марта 2011

Как можно XML-сериализовать следующее свойство:

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

Я пытался использовать XmlElement, XmlArray и XmlArrayItem, но безрезультатно.

Ответы [ 4 ]

2 голосов
/ 04 марта 2011

Согласно Microsoft, индексатор нельзя сериализовать с помощью XMLSerializer

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

Примечание. Сериализация XML не преобразует методы, индексаторы, закрытые поля или чтение.только свойства (кроме коллекций только для чтения).

2 голосов
/ 04 марта 2011

XmlSerializer не работает с индексаторами, вам придется либо реализовать IXmlSerializable, либо (лучше) использовать суррогатное свойство, чтобы выполнить тяжелую работу за вас.

1 голос
/ 28 января 2012

Самый простой способ - реализовать IEnumerable и соответствующий метод Add.

Например, если ваш индексатор использует List для хранения вашего списка, следующий код должен выполнить эту работу:

AddIEnumerable к списку реализуемых интерфейсов.Инициализируйте _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 , который включает следующее примечание:

XmlSerializer предоставляет особый режим для классов, которые реализуют IEnumerableили ICollection.Класс, реализующий IEnumerable, должен реализовывать открытый метод Add, который принимает один параметр.Параметр метода Add должен иметь тот же тип, который возвращается из свойства Current для значения, возвращаемого из GetEnumerator или одной из основ этого типа.Класс, который реализует ICollection (например, CollectionBase) в дополнение к IEnumerable, должен иметь открытое индексированное свойство Item (indexer в C #), которое принимает целое число, и у него должно быть открытое свойство Count типа integer.Параметр метода Add должен быть того же типа, который возвращается из свойства Item или одной из основ этого типа.Для классов, которые реализуют ICollection, значения для сериализации извлекаются из индексированного свойства Item, а не путем вызова GetEnumerator.

1 голос
/ 04 марта 2011

Нельзя сериализовать свойство индексатора.Лучшее, что вы можете сделать - это предоставить другое свойство (сериализуемое в 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...
        }
    }

}

...