以下代码编译:
class Testing<TKey, TValue>
{
public bool Test(TKey key)
{
return key == null;
}
}
但是,TKey 可以是值类型,并且可能不允许值“null”。
我知道这个程序的结果,以及如何添加约束。我想知道的是,当 TKey 不受“类”限制时,为什么编译器不允许这样做?
在各种情况下能够做到这一点很方便。如果TKey
是不可为空的值类型,则比较的结果将始终为假。(JITter 可能会完全删除该分支 - 不要忘记,尽管所有引用类型共享一个 JITted 代码版本,但它会为每个值类型重新 JIT。)
编辑:一个有趣的用途就是允许Nullable<T>
与 null 进行比较。TFoo=Nullable<T>
不满足or约束。_where TFoo : class
where TFoo : struct
至于“为什么”,我不确定。但要修复它,您可以使用default(T)
而不是null
.
因为它将您的变量转换为对象并使用 object == 运算符对于值类型,它始终为 false。
因为 csharp 中的一切都是对象。
换句话说,C# 中的每个类型都直接或间接地派生自对象类类型。
例子
using System;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
struct SimpleStruct
{
int a;
public SimpleStruct(int a)
{
this.a = a;
}
}
enum SimpleEnum
{
a = 1,
b = 2,
}
static void Main(string[] args)
{
SimpleStruct tp = new SimpleStruct(2);
object ob = tp;
if (ob != null)
{
Console.WriteLine("struct is an object : " + ob);
tp = (SimpleStruct)ob;
}
SimpleEnum tp2 = SimpleEnum.a;
ob = tp2;
if (ob != null)
{
Console.WriteLine("enum is an object : " + ob);
tp2 = (SimpleEnum)ob;
}
Console.ReadKey();
}
}
}
因为 TKey 可以是可为空的类型。
由于 C# 2.0 struct 可与 null 进行比较。这就是为什么您可以编写 0 == null 而没有编译错误的原因。