C#中的Serializable

2024-05-10 16:18
文章标签 c# .net netcore serializable

本文主要是介绍C#中的Serializable,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

     Serializable 表示序列化。那么什么是序列化呢?何时何地采用序列化?

一、序列化的一些简单概念(也有称为串行化)
       序列化是指存储和获取磁盘文件、内存或其他地方中的对象。序列化后的对象可以在网络之间进行传输。

       在序列化时,所有的实例数据都保存到存储介质上,在取消序列化时,对象会被还原,且不能与其原实例区别开来。

       只需给类添加Serializable属性,就可以实现序列化实例的成员。:[Serializable]

      与之对比,并行化是序列化的逆过程,数据从存储介质中读取出来,并赋给类的实例变量。

      栗子1:

[Serializable]
public class Person
{public Person()
{
}
public int Age;
public int WeightInPounds;
}

  栗子2:如果需要对部分字段序列化部分不序列化,可以按照如下方法实现:

[Serializable]  //序列化 
public class Person 
{public Person() 
{ 
} 
public int Age; 
[NonSerialized]//非序列化
public int WeightInPounds;
}

        在此过程中,先将对象的公共字段和私有字段以及类的名称(包括类所在的程序集)转换为字节流,然后再把字节流写入数据流。在随后对对象进行反序列化时,将创建出与原对象完全相同的副本。

以下是网络上的一些理论,可以参考参考慢慢理解一下:

      1、 公共语言运行时 (CLR) 管理对象在内存中的分布,.NET 框架则通过使用反射提供自动的序列化机制。

      2、对象序列化后,类的名称、程序集以及类实例的所有数据成员均被写入存储媒体中。对象通常用成员变量来存储对其他实例的引用。

      3、类序列化后,序列化引擎将跟踪所有已序列化的引用对象,以确保同一对象不被序列化多次。.NET 框架所提供的序列化体系结构可以自动正确处理对象图表和循环引用。对对象图表的唯一要求是,由正在进行序列化的对象所引用的所有对象都必须标记为 Serializable(请参阅基本序列化)。否则,当序列化程序试图序列化未标记的对象时将会出现异常。
      4、当反序列化已序列化的类时,将重新创建该类,并自动还原所有数据成员的值

二、基本序列化
要使一个类可序列化,最简单的方法是使用 Serializable 属性对它进行标记,如下所示,栗子实现:
[Serializable]
public class MyObject ...{
   
public int num1 = 0;
   
public int num2 = 0;
   
public String str = null;
}

以下代码片段说明了如何将此类的一个实例序列化为一个文件:
MyObject obj 
= new MyObject();
obj.num1 
= 5;
obj.num2 
= 12;
obj.str 
= "一些字符串";
IFormatter formatter 
= new BinaryFormatter();
Stream stream 
= new FileStream("MyFile.bin", FileMode.Create,
FileAccess.Write, FileShare.None);
formatter.Serialize(stream, obj);
stream.Close();
本例使用二进制格式化程序进行序列化。只需创建一个要使用的流和格式化程序的实例,然后调用格式化程序的 Serialize 方法。流和要序列化的对象实例作为参数提供给此调用。类中的所有成员变量(甚至标记为 
private 的变量)都将被序列化。
将对象还原到它以前的状态也非常容易。首先,创建格式化程序和流以进行读取,然后让格式化程序对对象进行反序列化。

三、自定义序列化

     可以通过在对象上实现 ISerializable 接口来自定义序列化过程。

     这一功能在反序列化后成员变量的值失效时尤其有用,但是需要为变量提供值以重建对象的完整状态。

     要实现 ISerializable,需要实现 GetObjectData 方法以及一个特殊的构造函数,在反序列化对象时要用到此构造函数。

     以下代码示例说明了如何在前一部分中提到的 MyObject 类上实现 ISerializable。
[Serializable]
public class MyObject : ISerializable
...{
   
public int num1;
   
public int num2;
   
public String str;
   
public MyObject()
   
...{
   }

   
protected MyObject(SerializationInfo info, StreamingContext context)
   
...{
     num1 
= info.GetInt32("i");
     num2 
= info.GetInt32("j");
     str 
= info.GetString("k");
   }

   
public virtual void GetObjectData(SerializationInfo info,
StreamingContext context)
   
...{
     info.AddValue(
"i", num1);
     info.AddValue(
"j", num2);
     info.AddValue(
"k", str);
   }

}

   在序列化过程中调用 GetObjectData 时,需要填充方法调用中提供的 SerializationInfo 对象。

       只需按名称/值对的形式添加将要序列化的变量。其名称可以是任何文本。只要已序列化的数据足以在反序列化过程中还原对象,便可以自由选择添加至 SerializationInfo 的成员变量。如果基对象实现了 ISerializable,则派生类应调用其基对象的 GetObjectData 方法。

       需要强调的是,将 ISerializable 添加至某个类时,需要同时实现 GetObjectData 以及特殊的构造函数。如果缺少 GetObjectData,编译器将发出警告。但是,由于无法强制实现构造函数,所以,缺少构造函数时不会发出警告。如果在没有构造函数的情况下尝试反序列化某个类,将会出现异常。在消除潜在安全性和版本控制问题等方面,当前设计优于 SetObjectData 方法。例如,如果将 SetObjectData 方法定义为某个接口的一部分,则此方法必须是公共方法,这使得用户不得不编写代码来防止多次调用 SetObjectData 方法。可以想象,如果某个对象正在执行某些操作,而某个恶意应用程序却调用此对象的 SetObjectData 方法,将会引起一些潜在的麻烦。

以上内容转载于网络资料,大家可以看看博客,更多详细内容查看一下内容(在前面添加3个w,后面加入“.html ”即可)
cnblogs.com/zwl12549/archive/2007/08/14/854718

四、我们的实战应用

     [Serializable]

 public partial class Plan
 {
  public Plan()
  {}
   private decimal _产品编号;
  private string _产品名称;.html

public decimal 产品编号
  {
   set{ _产品编号=value;}
   get{return _产品编号;}
  }

  public string 产品名称
  {
   set{ _产品名称=value;}
   get{return _产品名称;}
  }

}

**************************************************************************************************************************************************************************************

❤永葆一颗纯洁、宽容平和、仁慈谦卑和意气风发的心!

态度决定一切     努力改变命运

 

这篇关于C#中的Serializable的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/976935

相关文章

C#如何去掉文件夹或文件名非法字符

《C#如何去掉文件夹或文件名非法字符》:本文主要介绍C#如何去掉文件夹或文件名非法字符的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C#去掉文件夹或文件名非法字符net类库提供了非法字符的数组这里还有个小窍门总结C#去掉文件夹或文件名非法字符实现有输入字

C#之List集合去重复对象的实现方法

《C#之List集合去重复对象的实现方法》:本文主要介绍C#之List集合去重复对象的实现方法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C# List集合去重复对象方法1、测试数据2、测试数据3、知识点补充总结C# List集合去重复对象方法1、测试数据

C#实现将Office文档(Word/Excel/PDF/PPT)转为Markdown格式

《C#实现将Office文档(Word/Excel/PDF/PPT)转为Markdown格式》Markdown凭借简洁的语法、优良的可读性,以及对版本控制系统的高度兼容性,逐渐成为最受欢迎的文档格式... 目录为什么要将文档转换为 Markdown 格式使用工具将 Word 文档转换为 Markdown(.

Java调用C#动态库的三种方法详解

《Java调用C#动态库的三种方法详解》在这个多语言编程的时代,Java和C#就像两位才华横溢的舞者,各自在不同的舞台上展现着独特的魅力,然而,当它们携手合作时,又会碰撞出怎样绚丽的火花呢?今天,我们... 目录方法1:C++/CLI搭建桥梁——Java ↔ C# 的“翻译官”步骤1:创建C#类库(.NET

C#代码实现解析WTGPS和BD数据

《C#代码实现解析WTGPS和BD数据》在现代的导航与定位应用中,准确解析GPS和北斗(BD)等卫星定位数据至关重要,本文将使用C#语言实现解析WTGPS和BD数据,需要的可以了解下... 目录一、代码结构概览1. 核心解析方法2. 位置信息解析3. 经纬度转换方法4. 日期和时间戳解析5. 辅助方法二、L

使用C#删除Excel表格中的重复行数据的代码详解

《使用C#删除Excel表格中的重复行数据的代码详解》重复行是指在Excel表格中完全相同的多行数据,删除这些重复行至关重要,因为它们不仅会干扰数据分析,还可能导致错误的决策和结论,所以本文给大家介绍... 目录简介使用工具C# 删除Excel工作表中的重复行语法工作原理实现代码C# 删除指定Excel单元

C#使用MQTTnet实现服务端与客户端的通讯的示例

《C#使用MQTTnet实现服务端与客户端的通讯的示例》本文主要介绍了C#使用MQTTnet实现服务端与客户端的通讯的示例,包括协议特性、连接管理、QoS机制和安全策略,具有一定的参考价值,感兴趣的可... 目录一、MQTT 协议简介二、MQTT 协议核心特性三、MQTTNET 库的核心功能四、服务端(BR

C#继承之里氏替换原则分析

《C#继承之里氏替换原则分析》:本文主要介绍C#继承之里氏替换原则,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C#里氏替换原则一.概念二.语法表现三.类型检查与转换总结C#里氏替换原则一.概念里氏替换原则是面向对象设计的基本原则之一:核心思想:所有引py

C#实现访问远程硬盘的图文教程

《C#实现访问远程硬盘的图文教程》在现实场景中,我们经常用到远程桌面功能,而在某些场景下,我们需要使用类似的远程硬盘功能,这样能非常方便地操作对方电脑磁盘的目录、以及传送文件,这次我们将给出一个完整的... 目录引言一. 远程硬盘功能展示二. 远程硬盘代码实现1. 底层业务通信实现2. UI 实现三. De

C#通过进程调用外部应用的实现示例

《C#通过进程调用外部应用的实现示例》本文主要介绍了C#通过进程调用外部应用的实现示例,以WINFORM应用程序为例,在C#应用程序中调用PYTHON程序,具有一定的参考价值,感兴趣的可以了解一下... 目录窗口程序类进程信息类 系统设置类 以WINFORM应用程序为例,在C#应用程序中调用python程序