问题描述
对C#理解不深,使用XmlSerializer序列化时,可以序列化ArrayList,但不能序列化ArrayList[]。各位大侠能否帮我想想办法,一个项目因此类型卡住的了?代码如下:privatevoidbutton21_Click(objectsender,EventArgse){ArrayListaList=newArrayList();aList.Add("aaa");aList.Add("bbb");//XMLSerializer.Serialize(aList,"ArrList.xml");//序列化ArrayList没问题的ArrayList[]listarr=newArrayList[2];listarr[0]=newArrayList();listarr[1]=newArrayList();listarr[0].Add("1");listarr[0].Add(2);listarr[1].Add("111");listarr[1].Add(22.55);XMLSerializer.Serialize(listarr,"ArrListss.xml");}
[Serializable]publicclassXMLSerializer{publicstaticvoidSerialize(System.Collections.ArrayList[]al,stringfilePath){try{XmlSerializerformatter=newXmlSerializer(typeof(System.Collections.ArrayList[]));//此类型直接出错//XmlSerializerformatter=newXmlSerializer(typeof(System.Collections.ArrayList));StreamWritersw=newStreamWriter(filePath,false);//formatter.Serialize(sw,al[1]);//可以的sw.Flush();sw.Close();}catch(Exceptionex){MessageBox.Show(ex.Message);}}
XmlSerializerformatter=newXmlSerializer(typeof(System.Collections.ArrayList[]));//此类型直接出错
解决方案
本帖最后由 rell336 于 2015-07-09 22:44:15 编辑
解决方案二:
那你就遍历ArrayList[]进行序列化。既然不接受那个参数类型,就变通呗。
解决方案三:
序列化是需要实现相关接口的,c#里面预定义的实现了,你定义的没实现,如果想序列化一是就如duanzi_peng所言,变通一下没什么,或者你自己写一个类实现相关接口,下面是该类的帮助文档描述XmlSerializer特殊处理实现IEnumerable或ICollection的类。实现IEnumerable的类必须实现包含单个参数的公共Add方法。Add方法的参数的类型必须与从Current属性(此属性在从GetEnumerator返回的值上)返回的类型相同,或是该类型的基之一。除了IEnumerable外,实现ICollection(如CollectionBase)的类还必须有一个包含整数的公共Item索引属性(在C#中为索引器),且必须有一个整数类型的公共Count属性。Add方法的参数类型必须与从Item属性返回的类型相同,或者为此类型的基之一。对于实现ICollection的类,从具有索引的Item属性检索要序列化的值,而不是通过调用GetEnumerator。注意”特殊处理实现IEnumerable或ICollection的类“这句话
解决方案四:
序列化的目的当然是为了反序列化的哈!楼上解释得很详细,谢谢,但我的确需要“授人以鱼”!!(基础太差的了)不过,遍历后,追加到文件的ArrayList是不能反序列化的啊?!我所根据楼上的提示,想到的是用一个结构体,ArrayListSt,每个字段存ArrayList[]数组的ArrayList,比如ArrayListSt.a0=ArrayList[0],ArrayListSt.a1=ArrayList[1]来解决,序列化ArrayListSt后,反序列化ArrayListSt也能实现(已测试好)。但,是否我这方法很愚笨?赋值可能很多次的?因为实际上,ArrayList[]数组是嵌入在一个结构体中,其长度也不固定(那么我用我前面方法,就需要将此ArrayList[]数组提出来,嵌入到另外的ArrayListSt结构体中)?手动赋值,估计都又得弄半天的各位,有其他好办法吗?
解决方案五:
构造一个类实现IEnumerable或ICollection接口就可以了,可以自己枚举,这部分还真得自己写代码,也并不难,foreach(ArrayListalinaList){//将获得的al序列化为一个字符串,记住规则,将来可以按你的规则反序列化就可以}
解决方案六:
既然可以用ArrayList,那就用ArryList吧。一下代码经过测试:ArrayListlistarr=newArrayList();ArrayListlistsub1=newArrayList();listsub1.Add("1");listsub1.Add(2);ArrayListlistsub2=newArrayList();listsub2.Add("111");listsub2.Add(22.55);listarr.Add(listsub1);listarr.Add(listsub2);XMLSerializer.Serialize(listarr,"ArrListss.xml");
[Serializable]publicclassXMLSerializer{publicstaticvoidSerialize(System.Collections.ArrayListal,stringfilePath){try{TypetypeInfo=al.GetType();XmlSerializerformatter=newXmlSerializer(typeInfo);//此类型直接出错//XmlSerializerformatter=newXmlSerializer(typeof(System.Collections.ArrayList));StreamWritersw=newStreamWriter(filePath,false);formatter.Serialize(sw,al);sw.Flush();sw.Close();}catch(Exceptionex){MessageBox.Show(ex.Message);}}}
结果:<?xmlversion="1.0"encoding="utf-8"?><ArrayOfAnyTypexmlns:xsd="http://www.w3.org/2001/XMLSchema"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><anyTypexsi:type="ArrayOfAnyType"><anyTypexsi:type="xsd:string">1</anyType><anyTypexsi:type="xsd:int">2</anyType></anyType><anyTypexsi:type="ArrayOfAnyType"><anyTypexsi:type="xsd:string">111</anyType><anyTypexsi:type="xsd:double">22.55</anyType></anyType></ArrayOfAnyType>
解决方案七:
经过多次研究,把源代码的ArrayList[]改为ArrayList也不是一件非常麻烦的事情,我现在已经完成,并运行正常。就是把ArrayList[]中括号里面的index给去掉,本来是NitTable[0]和NitTable[1]数组2个,添加到ArrayListNitTables下面,2个子ArrayList数组table_nit(实际是根据设备不同而创建1~4个table_nit)。这样就能序列化了,不能就放弃。