泛型中无界类型参数的规则(C#)

问题描述 投票:0回答:1

我是泛型新手

我开始从 Microsoft 网站学习泛型

我无法理解以下有关无界类型参数的要点。

没有约束的类型参数,例如公共类中的 T SampleClass{},称为无界类型参数。

无界类型参数具有以下规则:您可以比较 无效的。如果将无界参数与 null 进行比较,则比较 如果类型参数是值类型,则始终返回 false。

我没有找到上述几点的任何例子。如果有人给我举例来理解这些要点,那就太好了。

c# generics null constraints nullable
1个回答
0
投票

这两个函数都会产生相同的 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);
© www.soinside.com 2019 - 2024. All rights reserved.