4

Dictionaryを実装する汎用クラスがあります。私は通常、キーを気にしないため、KeyValuePairsの代わりに値をループするカスタムGetEnumeratorを作成しました。簡単なサンプルを次に示します。

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

クラスにデータを追加しなかったため(メソッドのみを追加しました)、シリアル化できるようにするために、[DataMember]タグなしでクラスの先頭に[DataContract]を追加しました。これは、シリアル化/逆シリアル化に基本クラスのデータを使用するだけだと思いましたが、次のエラーが発生しました。

タイプ'Enumerator[System.String、SignalEngineeringTestPlanner.Asset]'のオブジェクトをタイプ'System.Collections.Generic.IEnumerator`1[System.Collections.Generic.KeyValuePair`2にキャストできません

これは、DataContractSerializerが子の列挙子を呼び出しており、ペアを期待しているのにAssetオブジェクトを取得しているため、混乱していることを意味していると思います。(1)DataContractSerializerに基本クラスの列挙子を使用するように指示する方法、または(2)特別な列挙関数を作成してDataContractSerializerにその1つだけを使用するように指示する方法はありますか?

4

2 に答える 2

1

派生クラスではなく、クラスでタイプをディクショナリとしてマークできます。欠点は、使用時にキャストする(または正しいタイプの別の参照を用意する)必要があることです。

于 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 に答える