加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – DataContract IEnumerable <>的序列化由'

发布时间:2020-12-15 17:24:12 所属栏目:百科 来源:网络整理
导读:是否可以序列化IEnumerable属性,其中值由’yield return’语句支持?如果有可能,怎么样?不是,为什么? 每当我尝试这样做时,我都会从DataContractSerializer获得NullReferenceException.一个例子: using System.Collections.Generic;using System.IO;using
是否可以序列化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:UsersCalebDocumentsVisual Studio 2010ProjectsIEnumerableProgram.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#语言设计者没有在迭代器类上公开任何可用于序列化或反序列化它们的功能.

只需使用反射手动序列化迭代器类上的字段将始终依赖于编译器实现细节.没有生产准备.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读