Как мне сказать DataContract использовать GetEnumerator базового класса? - PullRequest
4 голосов
/ 20 марта 2012

У меня есть универсальный класс, который реализует словарь.Я создал собственный GetEnumerator, который перебирает значения вместо KeyValuePairs, потому что меня обычно не волнуют ключи.Вот быстрый пример:

public class AssetHolder<T> : Dictionary<string, T>, IEnumerable, INotifyCollectionChanged, INotifyPropertyChanged where T : Asset
{
    // methods that don't relate to this post
    ...

    // enumeration methods
    IEnumerator System.Collections.IEnumerable.GetEnumerator() // this one is called by WPF objects like DataGrids
    {
        return base.Values.GetEnumerator();
    }
    new public IEnumerator<T> GetEnumerator() // this enumerator is called by the foreach command in c# code
    {
        return base.Values.GetEnumerator();
    }
}

Я не добавил никаких данных в свой класс (я только добавил методы), поэтому, чтобы сделать его сериализуемым, я добавил [DataContract] в верхнюю частькласс без каких-либо тегов [DataMember].Я полагал, что это просто использовало бы данные базового класса для сериализации / десериализации, но я получил следующую ошибку:

Невозможно привести объект типа 'Enumerator [System.String, SignalEngineeringTestPlanner.Asset]' to type 'System.Collections.Generic.IEnumerator`1 [System.Collections.Generic.KeyValuePair`2

Я думаю, это означает, что DataContractSerializer вызывает перечислитель дочернего элемента, и это сбивает с толку, поскольку он ожидает пару, но получает активобъект.Есть ли способ, которым я могу (1) сказать DataContractSerializer использовать перечислитель базового класса, или (2) создать специальную функцию перечисления и сказать DataContractSerializer использовать только эту функцию?

Ответы [ 2 ]

1 голос
/ 19 марта 2013

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

0 голосов
/ 20 марта 2012

Мне удалось устранить ошибки, которые вы получили, реализовав интерфейсы INotifyCollectionChanged и INotifyPropertyChanged в классе AssetHolder:

[DataContract]
public class AssetHolder<T> : Dictionary<string, T>, IEnumerable, INotifyCollectionChanged, INotifyPropertyChanged where T : Asset 
{
    IEnumerator IEnumerable.GetEnumerator() // this one is called by WPF objects like DataGrids 
    {
        return base.Values.GetEnumerator();
    }
    new public IEnumerator<T> GetEnumerator() // this enumerator is called by the foreach command in c# code 
    {
        return base.Values.GetEnumerator();
    }

    event NotifyCollectionChangedEventHandler INotifyCollectionChanged.CollectionChanged
    {
        add { throw new NotImplementedException(); }
        remove { throw new NotImplementedException(); }
    }

    event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged
    {
        add { throw new NotImplementedException(); }
        remove { throw new NotImplementedException(); }
    }
}
...