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#中lock关键字的使用小结

《C#中lock关键字的使用小结》在C#中,lock关键字用于确保当一个线程位于给定实例的代码块中时,其他线程无法访问同一实例的该代码块,下面就来介绍一下lock关键字的使用... 目录使用方式工作原理注意事项示例代码为什么不能lock值类型在C#中,lock关键字用于确保当一个线程位于给定实例的代码块中时

C# $字符串插值的使用

《C#$字符串插值的使用》本文介绍了C#中的字符串插值功能,详细介绍了使用$符号的实现方式,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧... 目录$ 字符使用方式创建内插字符串包含不同的数据类型控制内插表达式的格式控制内插表达式的对齐方式内插表达式中使用转义序列内插表达式中使用

C#中的Converter的具体应用

《C#中的Converter的具体应用》C#中的Converter提供了一种灵活的类型转换机制,本文详细介绍了Converter的基本概念、使用场景,具有一定的参考价值,感兴趣的可以了解一下... 目录Converter的基本概念1. Converter委托2. 使用场景布尔型转换示例示例1:简单的字符串到

C#监听txt文档获取新数据方式

《C#监听txt文档获取新数据方式》文章介绍通过监听txt文件获取最新数据,并实现开机自启动、禁用窗口关闭按钮、阻止Ctrl+C中断及防止程序退出等功能,代码整合于主函数中,供参考学习... 目录前言一、监听txt文档增加数据二、其他功能1. 设置开机自启动2. 禁止控制台窗口关闭按钮3. 阻止Ctrl +

C#解析JSON数据全攻略指南

《C#解析JSON数据全攻略指南》这篇文章主要为大家详细介绍了使用C#解析JSON数据全攻略指南,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、为什么jsON是C#开发必修课?二、四步搞定网络JSON数据1. 获取数据 - HttpClient最佳实践2. 动态解析 - 快速

C#连接SQL server数据库命令的基本步骤

《C#连接SQLserver数据库命令的基本步骤》文章讲解了连接SQLServer数据库的步骤,包括引入命名空间、构建连接字符串、使用SqlConnection和SqlCommand执行SQL操作,... 目录建议配合使用:如何下载和安装SQL server数据库-CSDN博客1. 引入必要的命名空间2.

C#读写文本文件的多种方式详解

《C#读写文本文件的多种方式详解》这篇文章主要为大家详细介绍了C#中各种常用的文件读写方式,包括文本文件,二进制文件、CSV文件、JSON文件等,有需要的小伙伴可以参考一下... 目录一、文本文件读写1. 使用 File 类的静态方法2. 使用 StreamReader 和 StreamWriter二、二进

C#中Guid类使用小结

《C#中Guid类使用小结》本文主要介绍了C#中Guid类用于生成和操作128位的唯一标识符,用于数据库主键及分布式系统,支持通过NewGuid、Parse等方法生成,感兴趣的可以了解一下... 目录前言一、什么是 Guid二、生成 Guid1. 使用 Guid.NewGuid() 方法2. 从字符串创建

C# 比较两个list 之间元素差异的常用方法

《C#比较两个list之间元素差异的常用方法》:本文主要介绍C#比较两个list之间元素差异,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1. 使用Except方法2. 使用Except的逆操作3. 使用LINQ的Join,GroupJoin

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

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