4

我有一个实现字典的通用类。我创建了一个自定义 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]”的对象转换为类型“System.Collections.Generic.IEnumerator`1[System.Collections.Generic.KeyValuePair`2

我认为这意味着 DataContractSerializer 正在调用孩子的枚举器并且它变得很困惑,因为它需要一对但它正在获取一个 Asset 对象。有没有一种方法可以(1)告诉 DataContractSerializer 使用基类的枚举器,或者(2)创建一个特殊的枚举函数并告诉 DataContractSerializer 只使用那个?

4

2 回答 2

1

您可以在类中将类型标记为 Dictionary 而不是派生类。缺点是你在使用它时必须强制转换它(或者有一个正确类型的单独引用)。

于 2013-03-18T23:43:45.217 回答
0

通过在 AssetHolder 类中实现 INotifyCollectionChanged 和 INotifyPropertyChanged 接口,我设法减轻了您遇到的错误:

[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(); }
    }
}
于 2012-03-19T21:09:48.140 回答