c# - 无法序列化我的 `ObservableDictionary<TKey,TValue>` 类

标签 c# .net serialization

我写了我的public sealed class ObservableDictionary<TKey,TValue> : NotifyPropertyChangedClass, INotifyCollectionChanged, IDictionary<TKey, TValue> where TKey: IEquatable<TKey>类(class)。

标记为[Serializable] .

但是我在尝试序列化 ObservableDictionary<Int64, String> 的实例时遇到异常.

异常信息:

The MS.Internal.Data.EnumerableCollectionView type in assembly "PresentationFramework, Version=4.0.0.0, Culture=neutral," isn't marked with PublicKeyToken=31bf3856ad364e35 as serializable.

但我从未使用过 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();
        }
    }
}

最佳答案

这与您的类关系不大,但与您存储在集合中的数据有关。似乎在您的集合中存储了一个 ViewObject,它在内部确实包含一个 EnumerableCollectionView 对象。

序列化数据时,您必须确定要序列化对象图的哪些部分。仅将对象放入您的集合中可能会导致一半的应用程序数据通过网络或光盘发送。发明 DataContractSerializer 是有充分理由的。

在序列化调用之前,您应该知道要序列化哪些数据。否则它可能会发生,例如在客户端服务器应用程序中,您试图反序列化位于仅存在于服务器上的程序集中的类型。

关于c# - 无法序列化我的 `ObservableDictionary<TKey,TValue>` 类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13431447/

相关文章:

json - 如何从列表中映射 Flutter JSON 字符串?

c# - 如何分组和计算逗号分隔字符串中项目的出现次数

c# - 多个客户端在同一个方法中都需要一些不同的功能

.net - IL 级代码调试器

c# - LINQ Parallel.ForEach<> 循环上的 lock 关键字

python - 如何创建 "serialized"版本的模型?

c# - 编译的dll中的序列化异常

c# - 如何从 C# 到 NLua 传递和迭代对象列表

c# - Azure 云存储 SDK UploadFromStreamAsync 不起作用

.net - FakeItEasy 创建一个假的类