Write1_Object(@"anyType",@"",((System.Object)a[ia]),true,false);
}
WriteEndElement();
对于集合类,在Xml序列化过程中都是要如上所述来写Xml的,显然的,对于实现了IDictionary接口的集合来讲,上面那个for循环是走不通的。
因为对于IDictionary来讲Item属性(也就是C#里的[]这个东西,也叫索引器,名字反正有点乱啦)是这样定义的:
[C#]
objectthis[
objectkey
]{get;set;}objectthis[
objectkey
]{get;set;}
上面是从结果上看,猜想最终序列化的时候,集合类是要以上面那样的循环方式进行序列化的,而实现了IDictionary接口的类对于那样的方式是不灵的,所以在生成临时文件的时候就不让它生成了,反正生成的DLL也是无法运行的,直接一个异常出来了。
其实在SDK上可以查到,关于Xml序列化有这么一段:
XmlSerializer可以以不同方式处理实现IEnumerable或ICollection的类(条件是这些类满足某些要求)。
实现IEnumerable的类必须实现带单个参数的公共Add方法。
Add方法的参数必须与从GetEnumerator方法返回的IEnumerator.Current属性所返回的类型一致(多态)。
除实现IEnumerable外还实现ICollection的类(如CollectionBase)必须有一个取整数的公共Item索引属性(在C#中为索引器),并且它必须有一个整数类型的公共Count属性。
传递给Add方法的参数必须与从Item属性返回的类型相同或与该类型的某个基的类型相同。
对于实现ICollection的类,要序列化的值将从索引Item属性检索,而不是通过调用GetEnumerator来检索。
另外请注意,除返回另一个集合类(实现ICollection的集合类)的公共字段之外,将不序列化公共字段和属性。
无法满足上述条件的都会抛出相应的异常,而实现了IDictionary接口的类显然是无法满足的,.Net在实现的时候,一开始就先判断是不是实现了IDictionary接口,发现实现了这个接口的直接就出来了,下面什么Add方法、Item属性呀都不管了。
还有一点,就是
l类(Class这一级)――包括集合类与非集合,
l非集合类 需要序列化的属性里的访问方法(不用序列化的属性例外),
l在集合类里,上面提到过的Add方法,Item属性、Count属性、Current属性的访问方法等,
如果有过SecurityAttribute声明的也是无法序列化的。
不过现在写代码那个SecurityAttribute用得是甚少――这个方面的东西除了照例子依样画葫芦过一下在实践中根本是没有涉足。
要序列化Hashtable其实就只是少一个整数类型的Item属性而已,在这上面是没有什么办法了。
想到SortedList这个东西很多方面跟Hashtable差不多,不过它还能依序取得集合中的元素,只是用的不是整数类型的Item属性,而是用GetByIndex()方法。
所以就用它来偷梁换柱一下了。
//[EnvironmentPermission(SecurityAction.Assert)]
publicclassMyCollection:
ICollection{
privateSortedListlist=newSortedList();
publicMyCollection(){
}
//[EnvironmentPermission(SecurityAction.Assert)]
publicvoidAdd(Itemitem){
list.Add(item.ID,item);
}
publicItemthis[intindex]{
get{return(Item)list.GetByIndex(index);}
}
ICollection成员#regionICollection成员
publicboolIsSynchronized{
get{
returnfalse;
}
}
publicintCount{
get{
returnlist.Count;
}
}
[EnvironmentPermission(SecurityAction.Assert)]
publicvoidCopyTo(Arrayarray,intindex){
list.CopyTo(array,index);
}
publicobjectSyncRoot{
get{
returnthis;
}
}
#endregion
IEnumerable成员#regionIEnumerable成员
publicIEnumeratorGetEnumerator(){
returnlist.GetEnumerator();
}
#endregion
}
Item是自定义的一个类。
没什么具体的意义。
这样偷一下,上面的这个MyCollection类就是可以被序列化的了,然后把SortedList其他属性包一下,就基本可以当成一个SortedList使用了,说它是Hashtable也差不多吧――外表基本看不出来。
不过局限性还是有喽。
它的Add方法的参数,与Item属性的类型必须是强类型的,不能用Objcet。
用Object类型,临时文件是可以生成,serialize=newXmlSerializer(typeof(Myclass));这一句是可以通过没异常了。
但真正序列化的时候,除非是一些基本的数据类型,否则它不知道如何去把那个类型写成相应的String,写Xml文件就出错了。
附加一些冗于的资料:
1/**////
2///序列化类。
3///
4publicclassSerializer
5{
6//防止被实例化。
7privateSerializer()
8{
9
10}
11/**////
12///静态构造函数仅在设置CanBinarySerialize值中使用一次。
13///
14staticSerializer()
15{
16SecurityPermissionsp=newSecurityPermission(SecurityPermissionFlag.SerializationFormatter);
17try
18{
19sp.Demand();
20CanBinarySerialize=true;
21}
22catch(SecurityException)
23{
24CanBinarySerialize=false;
25}
26}
27/**////
28///获取二进制序列化是否被使用。
29///
30publicstaticreadonlyboolCanBinarySerialize;
31/**////
32///将对象转化成二进制的数组。
33///
34///用于转化的对象。
35///返回转化后的数组,如果CanBinarySerialize为false则返回null。
36publicstaticbyte[]ConvertToBytes(objectobjectToConvert)
37{
38byte[]byteArray=null;
39
40if(CanBinarySerialize)
41{
42BinaryFormatterbinaryFormatter=newBinaryFormatter();
43using(MemoryStreamms=newMemoryStream())
44{
45
46binaryFormatter.Serialize(ms,objectToConvert);
47//设置是内存存储位置为0。
48ms.Position=0;
49//读取数组。
50byteArray=newByte[ms.Length];
51ms.Read(byteArray,0,byteArray.Length);
52ms.Close();
53}
54}
55returnbyteArray;
56}
57/**////
58///将对象以二进制形式存储到硬盘中。
59///
60///用于保存的对象。
61///文件路径。
62///如果存储成功则返回true,否则返回false。
63publicstaticboolSaveAsBinary(objectobjectToSave,stringpath)
64{
65if(objectToSave!
=null&&CanBinarySerialize)
66{
67byte[]ba=ConvertToBytes(objectToSave);
68if(ba!
=null)
69{
70using(FileStreamfs=newFileStream(path,FileMode.OpenOrCreate,FileAccess.Write))
71{
72using(BinaryWriterbw=newBinaryWriter(fs))
73{
74bw.Write(ba);
75returntrue;
76}
77}
78}
79}
80returnfalse;
81}
82/**////
83///将对象转化为Xml格式文件,该对象必须用[Serialize]标记,否则将抛出错误。
84///
85///用于序列化的标记。
86///返回Xml文本,如果对象为空则返回null。
87publicstaticstringConvertToString(objectobjectToConvert)
88{
89stringXml=null;
90
91if(objectToConvert!
=null)
92{
93//获取当前序列化对象。
94Typet=objectToConvert.GetType();
95
96XmlSerializerser=newXmlSerializer(t);
97//将序列化的结果保存到Xml中。
98using(StringWriterwriter=newStringWriter(CultureInfo.InvariantCulture))
99{
100ser.Serialize(writer,objectToConvert);
101Xml=writer.ToString();
102writer.Close();
103}
104}
105
106returnXml;
107}
108/**////
109///将对象序列化后以Xml格式存储于文件中。
110///
111///用于序列化的对象。
112///用于存储的文件路径。
113publicstaticvoidSaveAsXml(objectobjectToConvert,stringpath)
114{
115if(objectToConvert!
=null)
116{
117Typet=objectToConvert.GetType();
118
119XmlSerializerser=newXmlSerializer(t);
120
121using(StreamWriterwriter=newStreamWriter(path))
122{
123ser.Serialize(writer,objectToConvert);
124writer.Close();
125}
126}
127
128}
129/**////
130///将一个二进制的数组转化为对象,必须通过类型转化自己想得到的相应对象。
如果数组为空则返回空。
131///
132///用于转化的二进制数组。
133///返回转化后的对象实例,如果数组为空,则返回空对象。
134publicstaticobjectConvertToObject(byte[]byteArray)
135{
136objectconvertedObject=null;
137if(CanBinarySerialize&&byteArray!
=null&&byteArray.Length>0)
138{
139BinaryFormatterbinaryFormatter=newBinaryFormatter();
140using(MemoryStreamms=newMemoryStream())
141{
142ms.Write(byteArray,0,byteArray.Length);
143
144ms.Position=0;
145
146if(byteArray.Length>4)
147convertedObject=binaryFormatter.Deserialize(ms);
148
149ms.Close();
150}
151}
152returnconvertedObject;
153}
154/**////
155///将文件的数据转化为对象。
156///
157///文件路径。
158///希望得到的对象。
159///返回反序列化的对象。
160publicstaticobjectConvertFileToObject(stringpath,TypeobjectType)
161{
162objectconvertedObject=null;
163
164if(path!
=null&&path.Length>0)
165{
166using(FileStreamfs=newFileStream(path,FileMode.Open,FileAccess.Read))
167{
168XmlSerializerser=newXmlSerializer(objectType);
169convertedObject=ser.Deserialize(fs);
170fs.Close();
171}
172}
173returnconvertedObject;
174}
175/**////
176///将Xml格式的字符串反序列化为实例对象。
177///
178///Xml格式字符串。
179///反序列化后所期望的对象。
180///反序列化后所期望的对象,如果字符串为空,则返回空对象。
181publicstaticobjectConvertToObject(stringXml,TypeobjectType)
182{
183objectconvertedObject=null;
184
185if(!
WebHelper.IsNullOrEmpty(Xml))
186{
187using(StringReaderreader=newStringReader(Xml))
188{
189XmlSerializerser=newXmlSerializer(objectType);
190convertedObject=ser.Deserialize(reader);
191reader.Close();
192}
193}
194returnconvertedObject;
195}
196/**////
197///将Xml节点反序列化为实例对象。
198///
199///用于反序列化的Xml节点。
200///反序列化后所期望的对象。
201///反序列化后所期望的对象,如果字符串为空,则返回空对象。
202publicstaticobjectConvertToObject(XmlNodenode,TypeobjectType)
203{
204objectconvertedObject=null;
205
206if(node!
=null)
207{
208using(StringReaderreader=newStringReader(node.OuterXml))
209{
210
211XmlSerializerser=newXmlSerializer(objectType);
212
213convertedObject=ser.Deserialize(reader);
214
215reader.Close();
216}
217}
218returnconvertedObject;
219}
220/**////
221///加载一个二进制文件并将其转化为实例对象。
222///
223///文件路径。
224///返回转化后的实例对象。
225publicstaticobjectLoadBinaryFile(stringp