我尝试使用ToList选项序列化字典的值.
我发现在deserializtion过程中,我对所有序列化的对象都获取了null
当我使用内存流时它没有发生,当我使用.Net对象作为字典中的类型时没有发生.
下面是我创建的示例代码,用于显示问题
这段代码的输出是
字典:0-0
字典:1-1
清单:0
清单:1
字典:0-Null
字典:1-Null
清单:0
我发现在deserializtion过程中,我对所有序列化的对象都获取了null
当我使用内存流时它没有发生,当我使用.Net对象作为字典中的类型时没有发生.
下面是我创建的示例代码,用于显示问题
这段代码的输出是
字典:0-0
字典:1-1
清单:0
清单:1
字典:0-Null
字典:1-Null
清单:0
class Program { static void Main(string[] args) { A state = new A(); Stream stream = File.Open("D:\\temp\\temp.txt",FileMode.Create); BinaryFormatter bFormatter = new BinaryFormatter(); bFormatter.Serialize(stream,state); stream.Close(); state.PrintData(); stream = File.Open("D:\\temp\\temp.txt",FileMode.Open); bFormatter = new BinaryFormatter(); state = (A)bFormatter.Deserialize(stream); stream.Close(); state.PrintData(); } } [Serializable()] public class A : ISerializable { Dictionary<int,B> dic = new Dictionary<int,B>(); List<B> list = new List<B>(); public A() { for (int i = 0; i < 4; i++) { dic.Add(i,new B(i)); list.Add(new B(i)); } } public void PrintData() { foreach (keyvaluePair<int,B> kvp in dic) { Console.WriteLine("Dictionary: " + kvp.Key.ToString() + "-" + ((kvp.Value != null) ? kvp.Value.ToString() : "Null")); } foreach(B b in list) { Console.WriteLine("List: " + b.ToString()); } } public A(SerializationInfo info,StreamingContext context) { List<int> keys = info.GetValue("keys",typeof(List<int>)) as List<int>; List<B> values = info.GetValue("values",typeof(List<B>)) as List<B>; int count = keys.Count; if(count == values.Count) { for(int i = 0; i < count; i++) { dic[keys[i]] = values[i]; } } list = info.GetValue("list",typeof(List<B>)) as List<B>; } public void GetobjectData(SerializationInfo info,StreamingContext context) { info.AddValue("keys",dic.Keys.ToList(),typeof(List<int>)); info.AddValue("values",dic.Values.ToList(),typeof(List<B>)); List<B> listFromDic = new List<B>(dic.Values.ToList()); info.AddValue("list",listFromDic,typeof(List<B>)); } } [Serializable()] public class B : ISerializable { int foo; public B(int i) { foo = i; } public B(SerializationInfo info,StreamingContext context) { foo = info.GetInt32("foo"); } public void GetobjectData(SerializationInfo info,StreamingContext context) { info.AddValue("foo",foo); } public override string ToString() { return (foo != null) ? foo.ToString() : String.Empty; } }
解决方法
Serialize支持Dictionary.这是我修改过的代码.
public A(SerializationInfo info,StreamingContext context) { dic = info.GetValue("mapping",typeof(Dictionary<int,B>)) as Dictionary<int,B>; list = info.GetValue("list",StreamingContext context) { info.AddValue("mapping",dic,B>)); List<B> listFromDic = new List<B>(dic.Values.ToList()); info.AddValue("list",typeof(List<B>)); }
编辑:
op提到必须使用List.修改后的代码如下.无法在构造函数public A(SerializationInfo info,StreamingContext context)中初始化Dictionary dic.
因为:
无法保证对象反序列化的顺序.例如,如果一个类型引用尚未反序列化的类型,则会发生异常.如果要创建具有此类依赖关系的类型,则可以通过实现IDeserializationCallback接口和OnDeserialization方法来解决此问题.
以上para来自:ISerializable Interface
这意味着B不是在A的构造函数中创建的.
修订代码:
[Serializable()] public class A : ISerializable,IDeserializationCallback { Dictionary<int,B>(); List<B> list = new List<B>(); private List<int> keys = new List<int>(); public A() { for (int i = 0; i < 4; i++) { dic.Add(i,B> kvp in dic) { Console.WriteLine("Dictionary: " + kvp.Key.ToString() + "-" + ((kvp.Value != null) ? kvp.Value.ToString() : "Null")); } foreach (B b in list) { Console.WriteLine("List: " + b.ToString()); } } public A(SerializationInfo info,StreamingContext context) { keys = info.GetValue("keys",typeof(List<B>)) as List<B>; list = info.GetValue("list",typeof(List<B>)); } public void OnDeserialization(object sender) { dic = new Dictionary<int,B>(); int count = keys.Count; if (count == list.Count) { for (int i = 0; i < count; i++) { dic[keys[i]] = list[i]; } } } }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。