1. C# 序列化介绍
序列化是指将对象转换成字节流,从而存储对象或将对象传输到内存、数据库或文件的过程。 它的主要用途是保存对象的状态,以便能够在需要时重新创建对象。 反向过程称为“反序列化”。
主要用途:
- 使用 Web 服务将对象发送到远程应用程序
- 将对象从一个域传递到另一个域
- 将对象通过防火墙传递为 JSON 或 XML 字符串
- 跨应用程序维护安全或用户特定的信息
序列化方式:
- 二进制序列化保持类型保真,这对于多次调用应用程序时保持对象状态非常有用。 例如,通过将对象序列化到剪贴板,可在不同的应用程序之间共享对象。 您可以将对象序列化到流、磁盘、内存和网络等。 远程处理使用序列化,“按值”在计算机或应用程序域之间传递对象。
- XML 和 SOAP 序列化只序列化公共属性和字段,并且不保持类型保真。 当您希望提供或使用数据而不限制使用该数据的应用程序时,这一点非常有用。 由于 XML 是开放式的标准,因此它对于通过 Web 共享数据来说是一个理想选择。 SOAP 同样是开放式的标准,这使它也成为一个理想选择。
- JSON 序列化只序列化公共属性,并且不保持类型保真。 JSON 是开放式的标准,对于通过 Web 共享数据来说是一个理想选择。
2.XML序列化与反序列化
2.1 XML序列化代码示例
使用 XmlSerializer
类从某个类将对象写入 XML
文件。
public class XMLWrite
{
static void Main(string[] args)
{
WriteXML();
}
//新建一个book类
public class Book
{
public String title { get; set; } = String.Empty;
public String content { get; set; } = String.Empty;
}
public static void WriteXML()
{
Book overview = new Book();
overview.title = "Serialization Overview";
overview.content = "智能建造小硕";
//新建一个Book类型的XML类
System.Xml.Serialization.XmlSerializer writer =
new System.Xml.Serialization.XmlSerializer(typeof(Book));
//获取系统指定文件夹的路径,
var path = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "//SerializationOverview.xml";
System.IO.FileStream file = System.IO.File.Create(path);
writer.Serialize(file, overview);
file.Close();
Console.WriteLine("序列化成功");
}
}
运行结果
保存的XML文件,在C盘系统默认文件所在文件夹下:
2.2 XML反序列化代码示例
使用 XmlSerializer
类从某个类将对象写入 XML
文件。
public class XMLWrite
{
static void Main(string[] args)
{
ReadXML();
}
//新建一个book类
public class Book
{
public String title { get; set; } = String.Empty;
public String content { get; set; } = String.Empty;
}
public static void ReadXML()
{
//读取XML序列化的文件进行反序列化
System.Xml.Serialization.XmlSerializer reader =
new System.Xml.Serialization.XmlSerializer(typeof(Book));
var path = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "//SerializationOverview.xml";
System.IO.StreamReader file = new System.IO.StreamReader(path);
Book overview = (Book)reader.Deserialize(file);
file.Close();
Console.WriteLine(overview.title);
Console.WriteLine(overview.content);
}
}
运行结果
Serialization Overview
智能建造小硕
3. JSON序列化与反序列化
3.1 Json序列化
代码示例一:
public class WeatherForecast
{
public DateTimeOffset Date { get; set; }
public int TemperatureCelsius { get; set; }
public string? Summary { get; set; }
}
public class Program
{
public static void Main()
{
var weatherForecast = new WeatherForecast
{
//求位于当前年月日内的时间
Date = DateTime.Parse("2022-08-30"),
TemperatureCelsius = 25,
Summary = "Hot"
};
string fileName = "G:\\Desktop\\archive1" + "\\WeatherForecast.json";
string jsonString = JsonSerializer.Serialize(weatherForecast);
File.WriteAllText(fileName, jsonString);
Console.WriteLine(File.ReadAllText(fileName));
}
}
小知识:
引用类型可以使用空引用表示一个不存在的值,而值类型通常不能表示为空。
例如:string str=null
; 是正确的,int i=null
; 编译器就会报错。
为了使值类型也可为空,就可以使用可空类型,即用可空类型修饰符"?“来表示,表现形式为"T?”例如:
DateTime? date = null
; // 等价于Nullable<DateTime> date = null;
在赋值时为了避免抛出异常,需要做一些判断:
int a = age==null? 0 : (int) a;
//或者
int a = age ?? 0
;
空合并运算符(??
)
用于定义可空类型和引用类型的默认值。
如果此运算符的左操作数不为null,则此运算符将返回左操作数,否则返回右操作数。
例如:a??b
当a为null时则返回b,a不为null时则返回a本身。
空合并运算符为右结合运算符,即操作时从右向左进行组合的。
如,“a??b??c”
的形式按“a??(b??c)”
计算。
参考:https://blog.csdn.net/weixin_38404507/article/details/108513074
运行结果:
{"Date":"2022-08-30T00:00:00+08:00","TemperatureCelsius":25,"Summary":"Hot"}
代码示例二:
using System.Text.Json;
namespace SerializeExtra
{
/// <summary>
/// 天气预测类
/// </summary>
public class WeatherForecast
{
public DateTimeOffset Date { get; set; }
public int TemperatureCelsius { get; set; }
public string? Summary { get; set; }
public string? SummaryField;
public IList<DateTimeOffset>? DatesAvailable { get; set; }
// 包含有一个字典
public Dictionary<string, HighLowTemps>? TemperatureRanges { get; set; }
//包含有一个数组
public string[]? SummaryWords { get; set; }
}
//高低温度类
public class HighLowTemps
{
public int High { get; set; }
public int Low { get; set; }
}
public class Program
{
public static void Main()
{
var weatherForecast = new WeatherForecast
{
Date = DateTime.Parse("2022-08-30"),
TemperatureCelsius = 25,
Summary = "Hot",
SummaryField = "Hot",
DatesAvailable = new List<DateTimeOffset>()
{ DateTime.Parse("2022-08-30"), DateTime.Parse("2022-08-31") },
TemperatureRanges = new Dictionary<string, HighLowTemps>
{
["Cold"] = new HighLowTemps { High = 20, Low = -10 },
["Hot"] = new HighLowTemps { High = 60, Low = 20 }
},
SummaryWords = new[] { "Cool", "Windy", "Humid" }
};
var options = new JsonSerializerOptions { WriteIndented = true };
//将对象转换为JSON
string jsonString = JsonSerializer.Serialize(weatherForecast, options);
//保存JSON文件
String path = @"G:\\Desktop\\archive1\\WeatherForecast.json";
StreamWriter fileInfo = new StreamWriter(path);
fileInfo.Write(jsonString);
fileInfo.Close();
Console.WriteLine(jsonString);
}
}
}
运行结果
{
"Date": "2022-08-30T00:00:00+08:00",
"TemperatureCelsius": 25,
"Summary": "Hot",
"DatesAvailable": [
"2022-08-30T00:00:00+08:00",
"2022-08-31T00:00:00+08:00"
],
"TemperatureRanges": {
"Cold": {
"High": 20,
"Low": -10
},
"Hot": {
"High": 60,
"Low": 20
}
},
"SummaryWords": [
"Cool",
"Windy",
"Humid"
]
}
3.2 Json反序列化
代码示例
//天气类
public class WeatherForecast
{
public DateTimeOffset Date { get; set; }
public int TemperatureCelsius { get; set; }
public string? Summary { get; set; }
public string? SummaryField;
public IList<DateTimeOffset>? DatesAvailable { get; set; }
public Dictionary<string, HighLowTemps>? TemperatureRanges { get; set; }
public string[]? SummaryWords { get; set; }
}
public class HighLowTemps
{
public int High { get; set; }
public int Low { get; set; }
}
public class Program
{
public static void Main()
{
String jsonString = File.ReadAllText(@"G:\\Desktop\\archive1\\WeatherForecast.json");
WeatherForecast? weatherForecast =
JsonSerializer.Deserialize<WeatherForecast>(jsonString);
Console.WriteLine($"Date: {weatherForecast?.Date}");
Console.WriteLine($"TemperatureCelsius: {weatherForecast?.TemperatureCelsius}");
Console.WriteLine($"Summary: {weatherForecast?.Summary}");
}
}
运行结果
Date: 2022/8/30 0:00:00 +08:00
TemperatureCelsius: 25
Summary: Hot
下一篇继续讲解二进制序列化
【C#进阶八】C#中的序列化与反序列化下(二进制序列化、XML序列化及JSON序列化)
参考资料:
https://docs.microsoft.com/zh-cn/dotnet/standard/serialization/
欢迎关注公众号【智能建造小硕】(分享计算机编程、人工智能、智能建造、日常学习和科研经验等,欢迎大家关注交流。)