之前
使用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】,邀你加入技术交流群