Search code examples
c#serializationforeachdatacontractenumerator

How do I tell DataContract to use the base class's GetEnumerator?


I have a generic class that implements Dictionary. I created a custom GetEnumerator that loops over the values instead of KeyValuePairs because I usually don't care about the keys. Here is a quick sample:

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 didn't add any data to my class (I only added methods), so in order to make it serializable, I added [DataContract] to the top of the class without any [DataMember] tags. I figured that this would simply use the base class's data for serialization/deserialization, but I got the following error:

Unable to cast object of type 'Enumerator[System.String,SignalEngineeringTestPlanner.Asset]' to type 'System.Collections.Generic.IEnumerator`1[System.Collections.Generic.KeyValuePair`2

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


Solution

  • You can mark the type as Dictionary in your class instead of your derived class. The downside is that you will have to cast it (or have a separate reference with the correct type) when you're using it.