【问题标题】:How do I tell DataContract to use the base class's GetEnumerator?如何告诉 DataContract 使用基类的 GetEnumerator?
【发布时间】:2012-03-19 20:59:54
【问题描述】:

我有一个实现 Dictionary 的通用类。我创建了一个自定义 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 只使用那个?

【问题讨论】:

    标签: c# serialization foreach datacontract enumerator


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      我设法通过在 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(); }
          }
      }
      

      【讨论】:

      • 糟糕,如果我不清楚,抱歉。问题不在于编译(我已经实现了这些成员)。这个问题更多地与 DataContractSerializer 如何看待类有关。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-24
      • 1970-01-01
      相关资源
      最近更新 更多