我写了public sealed class ObservableDictionary<TKey,TValue> : NotifyPropertyChangedClass, INotifyCollectionChanged, IDictionary<TKey, TValue> where TKey: IEquatable<TKey>
课程。
标记为[Serializable]
。
但是当我尝试序列化ObservableDictionary<Int64, String>
的实例时,我遇到了异常。
异常消息:
程序集中的MS.Internal.Data.EnumerableCollectionView类型 “PresentationFramework,Version = 4.0.0.0,Culture = neutral”,不是 用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();
}
}
}
答案 0 :(得分:2)
这与您的课程有关,但与您在集合中存储的数据有关。看来你的集合中存储了一个ViewObject,它在内部确实包含一个EnumerableCollectionView对象。
序列化数据时,必须确定要对序列化的对象图的哪些部分。只是将对象放入集合中可能会导致一半的应用程序数据通过网络或光盘发送。 DataContractSerializer的发明有很好的理由。
您应该在序列化调用之前知道要序列化的数据。否则它可能发生在例如在客户端服务器应用程序中,您尝试反序列化位于仅存在于服务器上的程序集中的类型。