DataContract IEnumerable <> serialization supported by return return statements

Is it possible to serialize the IEnumerable property where values ​​are supported by yield return operations? If possible, how? This is not so, why?

I get a NullReferenceException from a DataContractSerializer whenever I try to do this. Example:

 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() { } } } 

Exclusion Details:

 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, Object obj, Boolean isDeclaredType, Boolean writeXsiType, Int32 declaredTypeID, RuntimeTypeHandle declaredTypeHandle) at WriteTestToXml(XmlWriterDelegator , Object , XmlObjectSerializerWriteContext , ClassDataContract ) at System.Runtime.Serialization.ClassDataContract.WriteXmlValue(XmlWriterDelegator xmlWriter, Object obj, XmlObjectSerializerWriteContext context) at System.Runtime.Serialization.XmlObjectSerializerWriteContext.WriteDataContractValue(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle declaredTypeHandle) at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithoutXsiType(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle declaredTypeHandle) at System.Runtime.Serialization.DataContractSerializer.InternalWriteObjectContent(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver) at System.Runtime.Serialization.DataContractSerializer.InternalWriteObject(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver) at System.Runtime.Serialization.XmlObjectSerializer.WriteObjectHandleExceptions(XmlWriterDelegator writer, Object graph, 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, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart() InnerException: 

This is in .NET 4.0, running inside Visual Studio 2010

+4
source share
1 answer

Consider the following sequence:

 var file = File.Open("a.txt"); yield return ""; //#1 yield return new StreamReader(file).ReadToEnd(); 

Imagine that this sequence is listed at point 1 and suspended. Even if you could serialize it, how would you restore it? DataContractSerializer cannot magically open your file again.

There is no reliable way to restore / deserialize a sequence with performance support, since such a sequence can do anything. It can open a message box or format your hard drive.

This is why C # developers have not revealed any functionality of their iterator classes that can be used for serialization or deserialization.

Simply manually serializing the fields in the iterator class using reflection will always rely on the details of the compiler implementation. Not ready for production.

+2
source

Source: https://habr.com/ru/post/1399083/


All Articles