是否可以序列化IEnumerable属性,其中值由’yield return’语句支持?如果有可能,怎么样?不是,为什么?
每当我尝试这样做时,我都会从DataContractSerializer获得NullReferenceException.一个例子:
using System.Collections.Generic; using System.IO; using System.Runtime.Serialization; namespace IEnumerableTest { class Program { static void Main(string[] args) { DataContractSerializer ser = new DataContractSerializer(typeof(Test)); using (FileStream writer = new FileStream("test.xml",FileMode.Create)) { Test test = new test(); //NullReferenceException thrown by the next call //if YieldValues is flagged as [DataMember] ser.WriteObject(writer,test); } } } [DataContract(Name = "Test")] public class Test { List<int> values = new List<int>() { 1,2,3,4,5,6,7,8 }; //This property serializes without issue [DataMember] public IEnumerable<int> Values { get { return values; } } //Attempting to serialize this member results in a NullReferenceException [DataMember] public IEnumerable<int> YieldValues { get { foreach (int value in values) { yield return value; } } } public test() { } } }
例外细节:
System.NullReferenceException was unhandled Message=Object reference not set to an instance of an object. Source=System.Runtime.Serialization StackTrace: at System.Runtime.Serialization.XmlObjectSerializerWriteContext.OnHandleIsReference(XmlWriterDelegator xmlWriter,DataContract contract,Object obj) at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithxsitype(XmlWriterDelegator xmlWriter,Object obj,RuntimeTypeHandle objectTypeHandle,Type objectType,Int32 declaredTypeID,RuntimeTypeHandle declaredTypeHandle,Type declaredType) at System.Runtime.Serialization.XmlObjectSerializerWriteContext.InternalSerialize(XmlWriterDelegator xmlWriter,Boolean isDeclaredType,Boolean writexsitype,RuntimeTypeHandle declaredTypeHandle) at WriteTestToXml(XmlWriterDelegator,Object,XmlObjectSerializerWriteContext,ClassDataContract ) at System.Runtime.Serialization.ClassDataContract.WriteXmlValue(XmlWriterDelegator xmlWriter,XmlObjectSerializerWriteContext context) at System.Runtime.Serialization.XmlObjectSerializerWriteContext.WriteDataContractValue(DataContract dataContract,XmlWriterDelegator xmlWriter,RuntimeTypeHandle declaredTypeHandle) at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithoutxsitype(DataContract dataContract,RuntimeTypeHandle declaredTypeHandle) at System.Runtime.Serialization.DataContractSerializer.InternalWriteObjectContent(XmlWriterDelegator writer,Object graph,DataContractResolver dataContractResolver) at System.Runtime.Serialization.DataContractSerializer.InternalWriteObject(XmlWriterDelegator writer,DataContractResolver dataContractResolver) at System.Runtime.Serialization.XmlObjectSerializer.WriteObjectHandleExceptions(XmlWriterDelegator writer,DataContractResolver dataContractResolver) at System.Runtime.Serialization.XmlObjectSerializer.WriteObject(XmlDictionaryWriter writer,Object graph) at System.Runtime.Serialization.XmlObjectSerializer.WriteObject(Stream stream,Object graph) at IEnumerableTest.Program.Main(String[] args) in F:\Users\Caleb\Documents\Visual Studio 2010\Projects\IEnumerable\Program.cs:line 19 at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly,String[] args) at System.AppDomain.ExecuteAssembly(String assemblyFile,Evidence assemblySecurity,String[] args) at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() at System.Threading.ThreadHelper.ThreadStart_Context(Object state) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback callback,Object state,Boolean ignoreSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext,Object state) at System.Threading.ThreadHelper.ThreadStart() InnerException:
这是在.NET 4.0中,在Visual Studio 2010中运行
解决方法
请考虑以下顺序:
var file = File.Open("a.txt"); yield return ""; //#1 yield return new StreamReader(file).ReadToEnd();
想象一下,这个序列被枚举到#1点并被暂停.即使您能够序列化它,您将如何恢复它? DataContractSerializer无法神奇地重新打开您的文件.
没有安全的方法来恢复/反序列化产量支持的序列,因为这样的序列可以做任何事情.它可以打开一个消息框或格式化您的硬盘.
这就是为什么C#语言设计者没有在迭代器类上公开任何可用于序列化或反序列化它们的功能.
只需使用反射手动序列化迭代器类上的字段将始终依赖于编译器实现细节.没有生产准备.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。