之前
使用JsonConverterAttribute,我们可以为任意类型自定义 Json 序列化。例如:
[JsonConverter(typeof(UserJsonConverter))]
public class User
{public string Name { get; set; }public override string ToString(){return Name;}
}public class UserJsonConverter : JsonConverter<User>
{public override User? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options){//演示代码,不实现具体序列化逻辑reader.Read();return new User { Name = "MyIO" };}
}反序列时将返回UserConverter生成的 User 实例:
var user = JsonSerializer.Deserialize<User>("{}");
但这不是本文的重点。重点是UserJsonConverter如何被实例化的。
查看JsonConverterAttribute的源码,JsonConverter的类型在构造函数中赋值给了ConverterType属性:
public class JsonConverterAttribute : JsonAttribute
{public JsonConverterAttribute(Type converterType){ConverterType = converterType;} public Type? ConverterType { get; private set; }
}而ConverterType的使用代码如下:
JsonConverter? converter;Type? type = converterAttribute.ConverterType;
if (type == null)
{converter = converterAttribute.CreateConverter(typeToConvert);
}
else
{converter = (JsonConverter)Activator.CreateInstance(type)!;
}也就是说,JsonConverte实例是通过反射(Activator.CreateInstance(type))生成的。
一般来说,反射的执行效率较低,这时我们注意到if分支,可以用CreateConverter方法创建实例。
修改实现代码如下:
public class UserJsonConverterAttribute : JsonConverterAttribute
{public override JsonConverter? CreateConverter(Type typeToConvert){return new UserJsonConverter();}
}[UserJsonConverterAttribute()]
public class User同样可以反序列成功,这时使用的是强类型的JsonConverter。
但是,这种方式也有一个缺点,每当我们实现了一个xxJsonConverter,就需要再定义一个xxJsonConverterAttribute。
而我们的目的,只是为了创建 JsonConverter 实例,代码逻辑相同,完全可以用范型方式实现。
但是在 C# 11 之前,是不支持这样定义的。
C# 11
在 C# 11 中,可以声明基类为System.Attribute的泛型类。
这样,上面的代码可以改造为如下形式:
public class GenericJsonConverterAttribute<T> : JsonConverterAttribute where T : JsonConverter, new()
{public override JsonConverter? CreateConverter(Type typeToConvert){return new T();}
}[GenericJsonConverter<UserJsonConverter>]
public class User[GenericJsonConverter<OrderJsonConverter>]
public class Order添加微信号【MyIO666】,邀你加入技术交流群