CustomSerialization我有一些对象必须序列化:classDisplayable{stringname;精灵图标;图标字段需要自定义序列化,因为Sprite已被序列化(在不同的文件中,由游戏引擎以其自己的格式),我只需要存储引用它们的方法(比如字符串,作为字典)。我尝试使用BinaryFormatter实现ISerializable和ISerializationSurrogate,但这两种方法在反序列化时都会创建Sprite对象的新实例,因此它们不适合我的情况。我想拥有与ISerializationSurrogate相同的功能,除了我不想要SetObjectData(objectobj,SerializationInfoinfo,StreamingContextcontext,ISurrogateSelectorselector)SetObjectData(objectobj,SerializationInfoinfo,StreamingContextcontext,ISurrogateSelectorselector)的第一个参数,因为我需要返回一个我已经拥有的对象,而不是从反序列化器接收一个新实例并用数据填充它。我也尝试过像SharpSerializer这样的外部库,但我不喜欢使用公共无参数构造函数的限制,它不允许您为特殊类自定义序列化。我读过有关ProtoBuffers的内容,但它不支持继承,我在其他地方需要它。所以我的要求是:有没有图书馆可以做到这一点?不然我是不是太挑剔了?您通常如何实现对存储在别处的对象的引用的序列化?先感谢您。编辑:这是我想要的publicvoidGetObjectData(objectobj,SerializationInfoinfo,StreamingContextcontext){Spritesprite=objasSprite;info.AddValue("spriteKey",sprite.name);}//这个函数的第一个参数是一个新实例化的Sprite,我不需要它;为了防止BinaryFormatter在反序列化过程中创建新的Sprite实例,在序列化过程中,您可以调用SerializationInfo.SetType(Type)来指定要插入到序列化流中的替代信息类型(通常是某种代理类型)。在反序列化SetObjectData()期间,SetObjectData()将传递代理实例而不是“真实”类型进行初始化。此代理类型必须依次实现IObjectReference,以便最终可以将“真实”对象插入到对象图中,特别是通过在sprite表中查找它。下面是这样的:classObjectReferenceProxy:IObjectReference{publicTRealObject{get;放;}#regionIObjectReference成员对象IObjectReference.GetRealObject(StreamingContextcontext){returnRealObject;}#endregion}publicsealedclassSpriteSurrogate:ObjectLookupSurrogate{staticDictionarysprites=newDictionary();静态字典spriteNames=newDictionary();publicstaticvoidAddSprite(stringname,Spritesprite){if(name==null||sprite==null)thrownewArgumentNullException();sprites.Add(名称,精灵);spriteNames.Add(sprite,名称);}publicstaticIEnumerableSprites{get{returnsprites.Values;}}protectedoverridestringGetId(SpriterealObject){if(realObject==null)returnnull;返回spriteNames[realObject];}protectedoverrideSpriteGetRealObject(stringid){if(id==null)returnnull;返回精灵[id];}}公共抽象类ObjectLookupSurrogate:ISerializationSurrogate,其中TRealObject:class{publicvoidRegister(SurrogateSelectorselector){foreach(vartypeinTypes)selector.AddSurrogate(type,newStreamingContext(StreamingContextStates.All),this);}IEnumerable类型{get{yieldreturntypeof(TRealObject);yieldreturntypeof(ObjectReferenceProxy);}}受保护的抽象TIdGetId(TRealObjectrealObject);受保护的抽象TRealObjectGetRealObject(TIdid);#regionISerializationSurrogateMemberspublicvoidGetObjectData(objectobj,SerializationInfoinfo,StreamingContextcontext){varoriginal=(TRealObject)obj;}varid=GetId(原始);info.AddValue("id",id);//使用Info.SetType()强制序列化程序在反序列化期间构造一个ObjectReferenceWrapper类型的对象。info.SetType(typeof(ObjectReferenceProxy));}publicobjectSetObjectData(objectobj,SerializationInfoinfo,StreamingContextcontext,ISurrogateSelectorselector){//构造了一个ObjectReferenceWrapper类型的对象,//使用序列化流中的id查找真正的精灵。varwrapper=(ObjectReferenceProxy)obj;varid=(TId)info.GetValue("id",typeof(TId));wrapper.RealObject=GetRealObject(id);返回包装器;}#endregion}然后像这样将它应用于BinaryFormatter:varselector=newSurrogateSelector();varspriteSurrogate=newSpriteSurrogate();spriteSurrogate.Register(选择器);BinaryFormatterbinaryFormatter=newBinaryFormatter(selector,newStreamingContext());示例Fiddle更新虽然上面的代码适用于.Net3.5及更高版本,但它在IObjectReference方面存在一些问题,尽管它在那里成功编译,但它显然是unity3d中的IObjectReference。以下内容也适用于.Net3.5及更高版本,并通过从ISerializationSurrogate.SetObjectData()返回实际对象来避免使用IObjectReference。因此它也应该在unity3d中工作(在评论中确认):publicsealedclassSpriteSurrogate:ObjectLookupSurrogate{staticDictionarysprites=newDictionary();静态字典spriteNames=newDictionary();publicstaticvoidAddSprite(stringname,Spritesprite){if(name==null||sprite==null)thrownewArgumentNullException();sprites.Add(名称,精灵);spriteNames.Add(sprite,名称);}publicstaticIEnumerableSprites{get{returnsprites.Values;}}protectedoverridestringGetId(SpriterealObject){if(realObject==null)returnnull;返回spriteNames[realObject];}protectedoverrideSpriteGetRealObject(stringid){if(id==null)returnnull;返回精灵[id];}}publicabstractclassObjectLookupSurrogate:ISerializationSurrogatewhereTRealObject:class{classSurrogatePlaceholder{}publicvoidRegister(SurrogateSelectorselector){foreach(vartypeinTypes)选择器,这);}IEnumerable类型{get{yieldreturntypeof(TRealObject);yieldreturntypeof(SurrogatePlaceholder);}}受保护的抽象TIdGetId(TRealObjectrealObject);受保护的抽象TRealObjectGetRealObject(TIdid);#regionISerializationSurrogateMemberspublicvoidGetObjectData(objectobj,SerializationInfoinfo,StreamingContextcontext){varoriginal=(TRealObject)obj;}varid=GetId(原始);info.AddValue("id",id);//使用Info.SetType()强制序列化程序在反序列化期间构造SurrogatePlaceholder类型的对象。info.SetType(typeof(SurrogatePlaceholder));}publicobjectSetObjectData(objectobj,SerializationInfoinfo,StreamingContextcontext,ISurrogateSelectorselector){//构造了一个SurrogatePlaceholder类型的对象,//使用序列化流中的id查找真实的精灵。varid=(TId)info.GetValue("id",typeof(TId));返回GetRealObject(id);}#endregion}样品小提琴#2以上就是《C#学习教程:自定义序列化分享》的全部内容。如果对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
