How to tell DataContract to use GetEnumerator base class?

I have a general class that implements a dictionary. I created a custom GetEnumerator that iterates over values ​​instead of KeyValuePairs, because I usually don't care about keys. Here is an example:

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(); } } 

I did not add any data to my class (I just added methods), so to make it serializable, I added [DataContract] to the top of the class without any [DataMember] tags. I figured this would just use base class data for serialization / deserialization, but I got the following error:

Cannot pass an object of type "Enumerator [System.String, SignalEngineeringTestPlanner.Asset]" to enter "System.Collections.Generic.IEnumerator`1 [System.Collections.Generic.KeyValuePair`2

I think this means that the DataContractSerializer calls the child enumerator, and it gets confused because it expects a couple, but receives an Asset object. Is there a way that I can (1) tell the DataContractSerializer to use the base class enumerator, or (2) create a special enumeration function and tell the DataContractSerializer to use only the one that is?

+4
source share
2 answers

You can mark this type as a Dictionary in your class instead of your derived class. The downside is that you have to use it (or have a separate link with the correct type) when you use it.

+1
source

I managed to increase the errors that you received by implementing the INotifyCollectionChanged and INotifyPropertyChanged interfaces in the AssetHolder class:

 [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(); } } } 
0
source

Source: https://habr.com/ru/post/1402316/


All Articles