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

在一个程序集中序列化,在另一个程序集中反序列化?Share

时间:2023-04-10 16:32:39 C#

在一个程序集中序列化,在另一个程序集中反序列化?我在两个项目中有相同的类,一个在运行时发送到另一个进程,该进程必须反序列化对象并使用它(假设两个对象相同但程序集名称不同,因此它们实际上被解释为两个不同的物种)。根据我的研究,由于以下原因,我提出的解决方案不起作用。Json.NET:给我一个例外,这两种类型不兼容(尝试在序列化设置中使用typename.all)。protobuf-net:要求我在任何地方添加属性或只给它属性名称(在v2中),由于我的对象的复杂性,这两者对我来说都是不可能的。BinaryFormatter:与protobuf->ton属性相同的原因。使用CommonAssembly:由于某些与我的项目架构相关的原因,我不能。那么有什么简单的方法可以序列化一种类型,然后将其反序列化为另一种类型(实际上是同一个类,但在不同的程序集中)?是的,绝对可以使用一个程序集中的类进行序列化,并使用Json.Net反序列化为另一个程序集的类。事实上,这是序列化的主要用例之一——在不同系统之间传输数据。您需要记住两件事:如果源程序集和目标程序集不同,则不应将实际的完全限定类型名称作为元数据包含在JSON中。换句话说,确保将TypeNameHandling设置设置为None(我认为这是默认设置)。如果包含类型名称元数据,则Json.Net将期望在接收端找到这些程序集,反序列化将失败,因为这些程序集不存在。如果您在类结构中使用接口而不是具体类型,那么您将需要创建一个或多个JsonConverter类来处理反序列化。当Json.Net看到一个接口时,它不知道要创建什么类型的具体类,因为它可以是任何东西。转换器可以查找JSON中可能存在的其他数据,并告诉Json.Net要实例化哪个具体类。如果JSON中没有明显的数据可用作该类型的指示器,则可以在序列化端使用转换器添加自定义指示器。下面是一些示例代码来演示我提出的概念。演示分为两部分。第一部分是“发送者”,它将组合的“图形”类结构序列化为JSON并将其写入文件。第二部分是“接收器”,它读取文件并将JSON反序列化为一组不同的类。您会注意到我有意在接收方中创建了一些与发送方中不同的类名,但它们具有相同的属性名称和结构,因此它仍然有效。您还会注意到接收器程序使用自定义JsonConverter来处理使用JSON中的某些属性作为指示符来创建正确的IFigure实例。寄件人使用System.Collections.Generic;使用System.IO;使用Newtonsoft.Json;namespaceSender{classProgram{staticvoidMain(string[]args){Diagramdiagram=newDiagram{Title="Flowchart",Shapes=newList{newCircle{Id=1,Text="Foo",Center=newPoint{X=1,Y=5},Radius=1.25},newLine{Id=2,A=newPoint{X=2.25,Y=5},B=newPoint{X=4,Y=5}},newRectangle{Id=3,Text="Bar",TopLeft=newPoint{X=4,Y=6.5},BottomRight=newPoint{X=8.5,Y=3.5}}}};stringjson=JsonConvert.SerializeObject(diagram,Formatting.Indented);File.WriteAllText(@"C:temptest.json",json);}}classDiagram{publicstringTitle{get;放;}公共列表形状{get;放;}}interfaceIShape{intId{get;放;}字符串文本{得到;放;}}抽象类AbstractShape:IShape{publicintId{get;放;}公共字符串文本{得到;放;}}classLine:AbstractShape{公共点A{get;秒等;}公共点B{得到;放;}}classRectangle:AbstractShape{publicPointTopLeft{get;放;}publicPointBottomRight{get;放;}}classCircle:AbstractShape{公共点中心{get;放;}publicdoubleRadius{get;放;}}classPoint{publicdoubleX{get;放;}publicdoubleY{get;放;}}}这是Sender程序生成的JSON输出文件:{"Title":"Flowchart","Shapes":[{"Center":{"X":1.0,"Y":5.0},"Radius":1.25,"Id":1,"Text":"Foo"},{"A":{"X":2.25,"Y":5.0},"B":{"X":4.0,"Y":5.0},"Id":2,"Text":null},{"TopLeft":{"X":4.0,"Y":6.5},"BottomRight":{"X":8.5,"Y":3.5},"Id":3,"Text":"Bar"}]}接收器使用系统;使用System.Collections.Generic;使用System.IO;使用系统文本;使用Newtonsoft.Json;使用Newtonsoft.Json.Linq;namespaceReceiver{classProgram{staticvoidMain(string[]args){stringjson=File.ReadAllText(@"C:temptest.json");JsonSerializerSettings设置=新JsonSerializerSettings();settings.Converters.Add(newFigureConverter());Chartchart=JsonConvert.DeserializeObject(json,settings);Console.WriteLine(图表);控制台.ReadKey();}}classFigureConverter:JsonConverter{publicoverrideboolCanConvert(TypeobjectType){return(objectType==typeof(IFigure));}}publicoverrideobjectReadJson(JsonReaderreader,TypeobjectType,objectexistingValue,JsonSerializerserializer){JObjectjo=JObject.Load(reader);if(jo["Center"]!=null){returnjo.ToObject(serializer);}elseif(jo["TopLeft"]!=null){returnjo.ToObject(serializer);}else{returnjo.ToObject(serializer);}}publicoverrideboolCanWrite{get{returnfalse;}}publicoverridevoidWriteJson(JsonWriterwriter,objectvalue,JsonSerializerserializer){thrownewNotImplementedException();}}classChart{publicstringTitle{get;放;}公共列表形状{get;放;}publicoverridestringToString(){StringBuildersb=newStringBuilder();sb.Append("图表:");sb.AppendLine(标题);foreach(形状中的IFigure图){sb.AppendLine(figure.ToString());}返回sb.ToString();}}interfaceIFigure{intId{get;放;}字符串文本{得到;放;}}抽象类AbstractFigure:IFigure{publicintId{get;放;}公共字符串文本{得到;放;}}classLine:AbstractFigure{公共点A{get;放;}公共点B{得到;放;}publicoverridestringToString(){returnstring.Format("Line:A={0},B={1}",A,B);}}classRectangle:AbstractFigure{publicPointTopLeft{get;放;}publicPointBottomRight{get;放;}publicoverridestringToString(){returnstring.Format("Rectangle:TopLeft={0},BottomRight={1}",TopLeft,BottomRight);}}classCircle:AbstractFigure{公共点中心{get;放;}publicdoubleRadius{get;放;}publicoverridestringToString(){returnstring.Format("Circle:Center={0},Radius={1}",Center,Radius);}}classPoint{publicdoubleX{get;set;}publicdoubleY{get;set;}publicoverridestringToString(){returnstring.Format("({0:0.##},{1:0.##})",X,Y);}}}Receiver程序的输出是这样的:DeserializationinChina?所有内容分享,如果对你和你有用需要了解更多C#学习教程,希望大家多多关注—Chart:FlowchartCircle:Center=(1,5),Radius=1.25Line:A=(2.25,5),B=(4,5)Rectangle:TopLeft=(4,6.5),BottomRight=(8.5,3.5)本文摘自网络,不代表立场,如涉及侵权,请点击右侧联系管理员删除,如需转载,请注明出处: