Проблемы с DataContractSerializer

Я пытаюсь заставить сериализатор DataContract работать с одним из моих классов.

Вот :

public class MyOwnObservableCollection<T> : ObservableCollection<T>, IDisposable
    where T : IObjectWithChangeTracker, INotifyPropertyChanged
{
    protected List<T> removedItems;

    [DataMember]
    public List<T> RemovedItems 
    {
    get { return this.removedItems;} 
    set { this.removedItems = value;}
    }
    // Other code removed for simplification
    // ...
    //
}

Важно понимать, что список RemovedItems заполняется автоматически, когда вы удаляете Item из ObservableCollection.

Теперь сериализуем экземпляр этого класса с помощью DataContractSerializer с одним элементом в списке deletedItems со следующим кодом:

MyOwnObservableCollection<Test> _Test = new MyOwnObservableCollection<Test>();
DataContractSerializer dcs = new DataContractSerializer(typeof(MyOwnObservableCollection<Test>));
XmlWriterSettings settings = new XmlWriterSettings() { Indent = true };
string fileName = @"Test.xml";

Insurance atest = new Test();
atest.Name = @"sfdsfsdfsff";
_Test.Add(atest);
_Test.RemoveAt(0); // The Iitem in the ObservableCollection is moved to the RemovedItems List/
using (var w = XmlWriter.Create(fileName, settings))
{
    dcs.WriteObject(w, _Test);
}

заканчивается ничем в XML-файле:

<?xml version="1.0" encoding="utf-8"?>
<ArrayOfTest xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="MyNameSpace" />

Почему игнорируется эта публичная собственность? Что я здесь пропустил?

TIA.


person Olivier MATROT    schedule 22.11.2012    source источник


Ответы (1)


Проблема здесь в том, что ваш класс является производным от коллекции, и поэтому DataContractSerializer сериализует только свои элементы, но не какие-либо дополнительные свойства, как указано здесь: Нет свойств при использовании CollectionDataContract.

Обходной путь заключается в использовании исходной (унаследованной) коллекции в качестве свойства, а не наследования от нее:

public class MyOwnObservableCollection<T> : IDisposable
    where T : IObjectWithChangeTracker, INotifyPropertyChanged
{
   readonly ObservableCollection<T> originalCollection = new ObservableCollection<T>();
   protected List<T> removedItems = = new List<T>();

   [DataMember]
   public List<T> RemovedItems 
   {
      get { return this.removedItems;} 
      set { this.removedItems = value;}
   }

   [DataMember]
   public ObservableCollection<T> OriginalCollection  
   {
      get { return this.originalCollection; }
   }

   // ...
}
person metalheart    schedule 23.11.2012
comment
Хороший улов. Я не использую ObservableCollection только для чтения, как было предложено жестко. Но идея здесь. - person Olivier MATROT; 26.11.2012