当前位置: 首页 > 编程语言 > C#

C#DataContract序列化,如何反序列化到现有实例分享

时间:2023-04-11 00:47:53 C#

C#DataContract序列化,如何反序列化到现有实例我有一个类,包含所有现有实例的静态字典,这些实例是在编译时定义的。基本上它看起来像这样:[DataContract]classFoo{privatestaticDictionaryinstances=newDictionary();[DataMember]privatelongid;publicstaticreadonlyFooA=Create(1);publicstaticreadonlyFooB=Create(2);publicstaticreadonlyFooC=Create(3);privatestaticFooCreate(longid){Foo实例=newFoo();实例.id=id;FooGet(longid){返回实例[id];还有其他字段,派生类,但这对问题无关紧要。只有id被序列化。反序列化此类实例时,我想使用Foo.Get(id)而不是获取新实例来获取已创建为静态字段(A、B或C)的实例。有简单的方法吗?我还没有找到任何我能理解的资源。在反序列化过程中,它(AFAIK)总是使用一个新对象(FormatterServices.GetUninitializedObject),但要让它在反序列化后替换对象(但在它们返回给调用者之前),您可以实现IObjectReference,如下所示:[DataContract]类Foo:IObjectReference{//完成...证书:静态类程序{staticvoidMain(){Foofoo=Foo.Get(2),clone;DataContractSerializerser=newDataContractSerializer(typeof(Foo));using(MemoryStreamms=newMemoryStream()){//通过DCS克隆它ser.WriteObject(ms,foo);ms.Position=0;克隆=(Foo)ser.ReadObject(ms);}安慰。WriteLine(ReferenceEquals(foo,clone));//true}}请注意,这里对MSDN上的部分信任方案有一些额外的说明。我遇到了类似的问题,我发现的最佳解决方案是添加一些包装类,用于管理需要序列化的实例。我不确定合同的确切签名。我使用了SerializableAttribute,它看起来不错。像这样:[Serializable]classFooSerializableWrapper:ISerializable{privatereadonlylongid;publicFooFoo{get{returnFoo.Get(id);}}publicFooSerializableWrapper(Foofoo){id=foo.id;}protectedFooSerializableWrapper(SerializationInfinfo,StreamingContextcontext){id=info.GetInt64("id");}voidGetObjectData(SerializationInfoinfo,StreamingContextcontext){info.AddValue("id",id);您可以使用OnDeserializingAttribute来查找您需要的内容。但是,这可能只允许您设置属性(因此您可以拥有等效于Copy方法的方法,该方法使用静态实例填充当前实例的所有属性。我想如果您真的想返回静态实例,您将可能必须编写自己的反序列化器...未经测试,但我认为您可以轻松实现反序列化器:obj=(Foo)base.Deserialize(reader);returnFoo.Get(obj.id);}}请注意,你必须做一些关于获取id的事情,因为它在你的代码中是私有的;此外,这假设你正在使用XML序列化;用您实际使用的任何东西替换继承。最后,这意味着您必须在反序列化对象时实例化此类型,这可能涉及更改一些代码和/或配置。没问题,只需使用2个类。在getObject方法中,您将获得对象[Serializable]publicclassMcRealObjectHelper:IObjectReference,ISerializable{Objectm_realObject;虚拟对象getObject(McObjectIdid){returnid.GetObject();}publicMcRealObjectHelper(SerializationInfoinfo,StreamingContextcontext){McObjectIdid=(McObjectId)info.GetValue("ID",typeof(McObjectId));m_realObject=getObject(id);如果(m_realObject==null)返回;输入t=m_realObject.GetType();MemberInfo[]members=FormatterServices.GetSerializableMembers(t,context);ListdeserializeMembers=newList(members.Length);列表数据=newList(members.Length);foreach(MemberInfomiinmembers){类型dataType=null;如果(mi.MemberType==MemberTypes.Field){FieldInfofi=miasFieldInfo;dataType=fi.FieldType;}elseif(mi.MemberType==MemberTypes.Property){PropertyInfopi=miasPropertyInfo;dataType=pi.PropertyType;}try{if(dataType!=null){data.Add(info.GetValue(mi.Name,dataType));反串izeMembers.Add(mi);}}catch(SerializationException){//缺少某些字段,新版本,跳过此字段}}FormatterServices.PopulateObjectMembers(m_realObject,deserializeMembers.ToArray(),data.ToArray());}publicobjectGetRealObject(StreamingContextcontext){returnm_realObject;}[SecurityPermission(SecurityAction.LinkDemand,Flags=SecurityPermissionFlag.SerializationFormatter)]publicvoidGetObjectData(SerializationInfoinfo,StreamingContextcontext){}}publicclassMcRealObjectBinder:SerializationBinder{StringassemVer;字符串类型Ver;publicMcRealObjectBinder(StringasmName,StringtypeName){assemVer=asmName;typeVer=typeName;}publicoverrideTypeBindToType(StringassemblyName,StringtypeName){TypetypeToDeserialize=null;if(assemblyName.Equals(assemVer)&&typeName.Equals(typeVer)){returntypeof(McRealObjectHelper);}typeToDeserialize=Type.GetType(String.Format("{0},{1}",类型名称,程序集名称));返回类型反序列化;然后,在反序列化的时候:以上是C#学习教程:C#DataContract序列化,如何反序列化到现有实例分享所有内容,如果对大家有用还有想了解更多C#学习教程的,我希望大家多多关注---BinaryFormatterbf=newBinaryFormatter(null,context);bf.Binder=newMcRealObjectBinder(YourType.Assembly.FullName,YourType.FullName);bf.Deserialize(memStream);本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如有转载请注明出处: