4

私は自分のpublic sealed class ObservableDictionary<TKey,TValue> : NotifyPropertyChangedClass, INotifyCollectionChanged, IDictionary<TKey, TValue> where TKey: IEquatable<TKey>クラスを書きました。

としてマークされてい[Serializable]ます。

しかし、のインスタンスをシリアル化しようとすると、例外が発生しましたObservableDictionary<Int64, String>

例外メッセージ:

アセンブリ"PresentationFramework、Version = 4.0.0.0、Culture = neutral"のMS.Internal.Data.EnumerableCollectionViewタイプは、PublicKeyToken=31bf3856ad364e35でシリアル化可能としてマークされていません。

しかし、私はそのMS.Internal.Data.EnumerableCollectionViewタイプを使用したことはありません。

私の間違いはどこですか?以下の私のコードは次のとおりです。

using System;
using System.ComponentModel;

namespace RememberEmployees {

    [Serializable]
    public abstract class NotifyPropertyChangedClass : INotifyPropertyChanged {        
        protected void NotifyPropertyChanged(string propertyName) {
            PropertyChangedEventHandler temp = PropertyChanged;
            if (temp != null) {
                temp(this, new PropertyChangedEventArgs(propertyName));
            }
        }        
        public event PropertyChangedEventHandler PropertyChanged;
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Collections.Specialized;

namespace RememberEmployees {   
    [Serializable]
    public sealed class ObservableDictionary<TKey,TValue> : NotifyPropertyChangedClass, 
        INotifyCollectionChanged, IDictionary<TKey, TValue> where TKey: IEquatable<TKey> {
        SortedDictionary<TKey, TValue> dict;

        IComparer<TKey> Comparer {
            get { return dict.Comparer; }
        }

        public ObservableDictionary() {
            dict = new SortedDictionary<TKey, TValue>();
            IsReadOnly = false;
        }

        private void NotifyCollectionChanged(NotifyCollectionChangedAction action) {
            NotifyCollectionChangedEventHandler temp = CollectionChanged;
            if (temp != null) {
                temp(this, new NotifyCollectionChangedEventArgs(action));
            }
        }

        private void NotifyCollectionChanged(NotifyCollectionChangedAction action, object item) {
            NotifyCollectionChangedEventHandler temp = CollectionChanged;
            if (temp != null) {
                temp(this, new NotifyCollectionChangedEventArgs(action, item));
            }
        }

        private void NotifyCollectionChanged(NotifyCollectionChangedAction action, int index) {
            NotifyCollectionChangedEventHandler temp = CollectionChanged;
            if (temp != null) {
                temp(this, new NotifyCollectionChangedEventArgs(action, index));
            }
        }

        private void NotifyCollectionChanged(NotifyCollectionChangedAction action, KeyValuePair<TKey, TValue> obj, int index) {
            NotifyCollectionChangedEventHandler temp = CollectionChanged;
            if (temp != null) {
                temp(this, new NotifyCollectionChangedEventArgs(action, obj, index));
            }
        }

        public event NotifyCollectionChangedEventHandler CollectionChanged;


        public void Add(TKey key, TValue value) {
            if (IsReadOnly)
                throw new Exception("Is Read Only");
            dict.Add(key, value);
            NotifyPropertyChanged("Count");
            NotifyCollectionChanged(NotifyCollectionChangedAction.Add, 
                dict.Cast<KeyValuePair<TKey, TValue>>().FirstOrDefault(n => n.Key.Equals(key)));
        }

        public bool ContainsKey(TKey key) {
            return dict.ContainsKey(key);
        }

        public ICollection<TKey> Keys {
            get { return dict.Keys; }
        }

        public bool Remove(TKey key) {
            if (IsReadOnly)
                throw new Exception("Is Read Only");
            if (!dict.Keys.Contains(key))
                return false;
            int x = 0;
            foreach (TKey item in dict.Keys) {
                if (item.Equals(key))
                    break;
                ++x;
            }
            KeyValuePair<TKey, TValue> val = dict.Cast<KeyValuePair<TKey, TValue>>().FirstOrDefault(n => n.Key.Equals(key));
            bool result = dict.Remove(key);
            if (result) {
                NotifyPropertyChanged("Count");
                NotifyCollectionChanged(NotifyCollectionChangedAction.Remove, val, x);
            }
            return result;
        }

        public bool Remove(KeyValuePair<TKey, TValue> item) {
            return Remove(item.Key);
        }

        public bool TryGetValue(TKey key, out TValue value) {
            return dict.TryGetValue(key, out value);
        }

        public ICollection<TValue> Values {
            get { return dict.Values; }
        }

        public TValue this[TKey key] {
            get {
                return dict[key];
            }
            set {
                dict[key] = value;
                NotifyCollectionChanged(NotifyCollectionChangedAction.Reset);
            }
        }

        public void Add(KeyValuePair<TKey, TValue> item) {
            Add(item.Key, item.Value);
        }

        public void Clear() {
            if (IsReadOnly)
                throw new Exception("Is Read Only");
            dict.Clear();
            NotifyCollectionChanged(NotifyCollectionChangedAction.Reset);
        }

        public bool Contains(KeyValuePair<TKey, TValue> item) {
            return dict.Contains(item);
        }

        public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex) {
            if (arrayIndex > dict.Count)
                throw new IndexOutOfRangeException();
            int max = dict.Count - arrayIndex <= array.Count() ? dict.Count - arrayIndex : array.Count();
            for (int i = 0; i < max; i++) {
                array[i] = dict.Skip(arrayIndex).ToArray()[i];
            }
        }

        public int Count {
            get { return dict.Count; }
        }
        bool readOnly;

        public bool IsReadOnly {
            get { return readOnly; }
            set { readOnly = value; NotifyPropertyChanged("IsReadOnly"); }
        }

        public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() {
            return dict.GetEnumerator();
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
            return dict.GetEnumerator();
        }
    }
}
4

1 に答える 1

2

これはクラスとは関係ありませんが、コレクションに保存したデータとは関係ありません。コレクションに、内部にEnumerableCollectionViewオブジェクトを含むViewObjectが格納されているようです。

データをシリアル化するときは、オブジェクトグラフのどの部分をシリアル化するかを確認する必要があります。コレクションにオブジェクトを配置するだけで、アプリケーションデータの半分がネットワーク経由またはディスクに送信される可能性があります。DataContractSerializerが発明されたのには十分な理由があります。

シリアル化を呼び出す前に、シリアル化するデータを知っておく必要があります。そうしないと、たとえばクライアントサーバーアプリケーションで、サーバー上にのみ存在するアセンブリにあるタイプを逆シリアル化しようとしている可能性があります。

于 2012-11-17T14:35:53.577 に答える