引子

今天写码时想检查泛型类传入的泛型参数的类型是什么(泛型约束也有约束不到的地方),结果大脑一片空白,发现对这方面没有什么了解就花空了解了下。

正文

举了三个例子

1
2
3
4
5
public class FSM<TState,t> {}
FSM<pl,int> s = new FSM<pl,int>();
Type type1 = s.GetType();
Type type2 = typeof(FSM<,>);
Type type3 = typeof(FSM<pl,int>);

type1为泛型实例,type2为泛型类型定义(GenericTypeDefinition) , type3为泛型类型(GenericType

再用Type.IsGenericTypeIsGenericTypeDefinition两个函数求证

1
2
3
Console.WriteLine(type1.Name+ " " + type1.IsGenericType + " "  + type1.IsGenericTypeDefinition);
Console.WriteLine(type2.Name+ " " + type2.IsGenericType + " " + type2.IsGenericTypeDefinition);
Console.WriteLine(type3.Name+ " " + type3.IsGenericType + " " + type3.IsGenericTypeDefinition);

输出:

1
2
3
FSM`2 True False
FSM`2 True True
FSM`2 True False

符合

所以怎么在他类获得一个特定泛型类的泛型参数?用这个

Type.GetGenericArguments()

例如 对type3求证:

1
2
Type[] types=type3.GetGenericArguments();
Console.WriteLine(types.Length+" "+ types[0].Name+" "+ types[1].Name);

输出为:

1
2 pl Int32

符合

接着如果对泛型类型定义执行GetGenericArguments()函数会有结果吗?

有的。

泛型类型定义因为没有传入泛型实参,所以结果是泛型形参.

求证:

1
2
Type[] types=type2.GetGenericArguments();
Console.WriteLine(types.Length+" "+ types[0].Name+" "+ types[1].Name);

输出:

1
2 TState t

符合

得到泛型参数,就可以检查是否是想要的类型了

一开始还想着用 types[1] is int来判断,还纳闷怎么会报False

哦,原来是自己脑瘫了。

找到了两个方式判断

  1. ```
    Type.IsEnum,.IsInterface .IsValueType等一系列其本身的属性
    但当我我想检查是不是Int时,发现没有途径判断

    1
    2
    3

    2. ```
    Type.IsInstanceOfType(Object? Instance)

    例如 想判断type3的第二个泛型参数是不是Int以及,就这样

    1
    2
    //传入目的类型的对象实例
    Console.WriteLine(types[1].IsInstanceOfType(1));

    输出为 True,符合

总结

概念:泛型实例,泛型类型(GenericType),泛型类型定义(GenericTypeDefinition)

函数:

  1. Type.IsGenericType 判断是否为泛型;

  2. Type.IsGenericTypeDefinition 判断是否为泛型类型定义;

  3. Type.GetGenericArguments() 获得泛型参数,如果Type为泛型类型定义则获得形参,反之实参;

  4. Type.IsGenericParameter() 判断是否为泛型形参,形参为True,实参为False;

  5. Type.IsEnum,.IsInterface .IsValueType...
    Type.IsInstanceOfType(Object? Instance)

    ​ 判断泛型参数是否为目的类型 ;

完….😝