当前位置: 首页 > 科技观察

.NET6新特性试用-System.Text.Json序列化代码自动生成

时间:2023-03-14 16:17:13 科技观察

前言几乎所有的.NET序列化程序都是基于反射实现的。PropertyType=ReflectionUtils.GetMemberUnderlyingType(成员);property.DeclaringType=member.DeclaringType;property.ValueProvider=CreateMemberValueProvider(成员);property.AttributeProvider=newReflectionAttributeProvider(member);...}反射为某些场景提供了强大的功能,但与直接编码相比,运行性能较差。例如,Newtonsoft.Json使用缓存进行了优化:publicvirtualJsonContractResolveContract(Typetype){ValidationUtils.ArgumentNotNull(type,nameof(type));return_contractCache.Get(type);}在.NET6中,为System.Text提供了源生成器.Json,可以在编译时生成序列化源代码。Demo使用起来非常简单。只需要实现一个继承自JsonSerializerContext的类,声明JsonSerializable,并指定序列化的类型:[JsonSerializable(typeof(WeatherForecast))]internalpartialclassWeatherForecastContext:JsonSerializerContext{}然后,就可以使用自动生成的WeatherForecastContext.Default.WeatherForecast对象作为参数对于序列化:varstr=JsonSerializer.Serialize(newWeatherForecast{TemperatureC=Random.Shared.Next(-20,55),Summary=Summaries[Random.Shared.Next(Summaries.Length)]},WeatherForecastContext.Default.WeatherForecast);varobj=JsonSerializer.Deserialize(str,WeatherForecastContext.Default.WeatherForecast);单步跟踪,可以看到生成的序列化代码如下,WriteNullValue();返回;}writer.WriteStartObject();writer.WriteNumber(PropName_TemperatureC,value.TemperatureC);writer.WriteNumber(PropName_TemperatureF,value.TemperatureF);作家。WriteString(PropName_Summary,value.Summary);writer.WriteEndObject();}此外,也可以使用JsonSourceGenerationOptionsAttribute对生成的序列化代码做一些调整,比如属性名的大小写:[JsonSourceGenerationOptions(PropertyNamingPolicy=JsonKnownNamingPolicy.CamelCase)][JsonSerializable(typeof(WeatherForecast))]internalpartialclassWeatherForecastContext:JsonSerializerContext{}结论是在编译时生成的代码可以为.NET应用程序带来很多好处,包括提高性能。官方测试结果显示,提升了近40%。有兴趣的朋友可以验证一下: