我是泛型新手
我开始从 Microsoft 网站学习泛型
我无法理解以下有关无界类型参数的要点。
没有约束的类型参数,例如公共类中的 T SampleClass{},称为无界类型参数。
无界类型参数具有以下规则:您可以比较 无效的。如果将无界参数与 null 进行比较,则比较 如果类型参数是值类型,则始终返回 false。
我没有找到上述几点的任何例子。如果有人给我举例来理解这些要点,那就太好了。
这两个函数都会产生相同的 IL;
bool Test1<T>(T val) => val == null;
bool Test2<T>(T val) where T:class => val == null;
IL_0000: ldarg.0
IL_0001: box !!T
IL_0006: ldnull
IL_0007: ceq
IL_0009: ret
如果调用者传入的是值类型参数;
Test1<int>(0) == false;
然后整数参数将被装箱在一个对象中,这将始终导致非空引用。因此,与
null
进行比较始终是错误的。
传入
Nullable<T>
参数也可以,并产生相同的 IL
bool Test3<T>(T? val) where T:struct => val == null;
bool Test4<T>(T? val) where T:struct => !val.HasValue;
IL_0000: ldarga.s val
IL_0002: call instance bool valuetype [System.Runtime]System.Nullable`1<!!T>::get_HasValue()
IL_0007: ldc.i4.0
IL_0008: ceq
IL_000a: ret
但是值类型没有默认的
==
运算符;
bool Test5<T>(T val) where T:struct => val == null;
bool Test6<T>(T val) where T:struct => val == default(T);
error CS0019: Operator '==' cannot be applied to operands of type 'T' and '<null>'
error CS0019: Operator '==' cannot be applied to operands of type 'T' and 'T'
您可以使用默认比较器;
public bool Test7<T>(T val) => EqualityComparer<T>.Default.Equals(val, default(T));
自 .net 7 起,您可以添加由 .net 数字类型实现的约束;
public bool Test8<T>(T val) where T : IEqualityOperators<T,T,bool> => val == default(T);