C# 11 新特性:泛型 Attribute

Posted dotNET跨平台

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C# 11 新特性:泛型 Attribute相关的知识,希望对你有一定的参考价值。

之前

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

以上是关于C# 11 新特性:泛型 Attribute的主要内容,如果未能解决你的问题,请参考以下文章

C# 2.0 新特性(上)

C#各版本新特性

C#各版本新特性(转)

《Inside C#》笔记 Attribute

C# 11 的新特性和改进前瞻

C# 11 的这个新特性,我愿称之最强!