1.前言
.Net7到.Net8各种魔改,几乎有些不认得了。本篇来看下.Net8支持的两个新功能,序列化变异。
2.接口层次结构序列化
先上代码,用以观察:
public interface IBase
{
public int Base { get; set; }
}
public interface IDerived : IBase
{
public int Derived { get; set; }
}
public class DerivedImplement : IDerived
{
public int Base { get; set; }
public int Derived { get; set; }
}
static void Main(string[] args)
{
IDerived value = new DerivedImplement { Base = 0,Derived= 1};
Console.WriteLine(JsonSerializer.Serialize(value));
Console.ReadLine();
}
这是官方的代码,注意看。接口IBse有成员变量Base,接口IDerived继承了IBase有成员变量Derived。
这段代码在.Net7里面只能打印出:
{"Derived":1}
因为这种接口层次的结构序列化并不完整,它只能识别出Derived这个成员变量。
在.Net8里面,它打印出:
{"Derived":1,"Base":0}
.Net8可以完整的识别出接口层次的结构,进而对接口的成员变量进行序列化,完整的把这两个变量都打印出来。
官方的解释:
实现的接口及其基接口的属性进行了序列化,意即:接口层次结构序列化。
一个小的功能,这种可以序列化接口层次的方式,可以方便了序列化的使用。简化了工作麻烦。
3.非公共成员包含序列化
可以使用
JsonIncludeAttribute 和 JsonConstructorAttribute 特性注释将非公共成员加入到给定类型的序列化协定中。
也就是说,在私有的成员上加入以上两个特性就可以把它序列化出来,序列化出来之后,还可以把它反序列化回去,显示类所在的:命名空间.类名+反序列化的类
代码演示:
public class MyPoco
{
[JsonConstructor]
internal MyPoco(int x) => X = x;
[JsonInclude]
internal int X { get; }
}
class Program
{
static void Main(string[] args)
{
string json = JsonSerializer.Serialize(new MyPoco(42)); // {"X":42}
Console.WriteLine(json);
Console.WriteLine(JsonSerializer.Deserialize<MyPoco>(json));
Console.ReadLine();
}
}
以上代码.Net8里面运行序列化之后如下:
{"X":42}
ConsoleApp1.Test+MyPoco
它把序列化的类MyPoco的私有成员变量X进行了JsonConstructor和JsonInclude特性标注,让其可以序列化。并且对其序列化的结果进行了反序列化,打印出了序列化类所在的
命名空间.类名+反序列化的类,也即如下:
ConsoleApp1.Test+MyPoco
这种怪异的操作还蛮有意思的。你还认识.Net吗?