像这样......它是像C++中的0
吗?还是某种"特殊"对象?或者完全不同?
-- 编辑 --
我知道它是什么,问题是 - 它是如何做到的
像这样......它是像C++中的0
吗?还是某种"特殊"对象?或者完全不同?
-- 编辑 --
我知道它是什么,问题是 - 它是如何做到的
由于您询问的是实现细节而不是语义,所以答案特定于给定的实现。
C# 中有三种“null”可能性:引用、指针和可空类型。
CLR 上的 C# 实现通过零位表示 null 引用。(其中位数是在运行特定版本 CLR 的托管指针大小)
不出所料,null 指针 同样也是这样表示。您可以在 C# 中进行演示,方法是制作一个不安全块,使其成为 void 的 null 指针,然后将其转换为 IntPtr,最后将 IntPtr 转换为 int(或在 64 位系统上转换为 long)。毫无疑问,您将得到零。
null 可空值类型 也是通过零来实现,但方式略有不同。 当您说:
int?j = null;
实际上我们创建的相当于:
struct NullableInt
{
int value;
bool hasValue;
}
通过适当的访问器方法等,当其中一个被赋空值时,我们将整个对象用零位填充。该值为整数零,hasValue被填充为零,因此变为false;带有hasValue字段设置为false的可空类型被认为是null。
我不知道其他C# / CLI实现的具体实现细节。如果它们不同,我会感到惊讶;这是实现null的明显且合理的方式。但如果你对特定实现细节有疑问,你需要向了解你感兴趣的实现的人提问。
由于Java和C#运行在虚拟机上,因此用于表示null的物理方式并不重要,并且在不同的实现中可能不相同。
重要的是null的行为,如语言规范所定义的(有关详细信息,请参见Dan和MRFerocius的答案)。基本上,它是引用类型变量可以持有的特殊值,不能被取消引用。
顺便提一下,作为一个参考点,Java序列化规范使用单个字节值0x70来表示空引用。
还有一种特殊的null类型,即表达式null的类型,它没有名称。由于null类型没有名称,因此不可能声明null类型的变量或将其转换为null类型。null引用是null类型表达式的唯一可能值。null引用始终可以转换为任何引用类型。在实践中,程序员可以忽略null类型,并假装null只是一个可以是任何引用类型的特殊字面量。
来自微软 MDSN:
null 关键字是一个字面量,表示一个空引用,即不引用任何对象。null 是引用类型变量的默认值。普通值类型不能为 null。但是,C# 2.0 引入了可空值类型。请参阅可空类型 (C# 编程指南)。
它是一个特殊的引用(与0区分开来),指向空。
它相当于
#define NULL (void*)0
在C++中,基本上是零。
编辑: 由于我显然没有正确表达这个答案...
我的意思是这样的:
由于C#运行在虚拟机中,Michael Borgwardt所说的是正确的,我们不知道它在幕后是如何表示的。但是,如果您采用以下代码:
unsafe static void Main(string[] args)
{
if (((void*)0) == null)
Console.WriteLine("true");
else
Console.WriteLine("false");
Console.ReadKey();
}
并在启用“允许不安全代码”的情况下,在控制台应用程序中编译它,您将看到在C#中,null确实等于(void*) 0。
null是指向“无”的“引用”,因此它指向实际上不存在的东西。
额外信息:C#引用类型可以指向null(即:无),而像int这样的值类型不能指向null,尽管值类型可以在Nullable泛型引用类型中使用。
Null字面上意味着什么都没有。一些语言(如PHP)在特定情况下将null等同于0、false、空字符串等。Java和C#是强类型语言,因此不会发生任何“有帮助”的隐式转换。所以null字面上就是null或者什么都没有。Null只等于null,其他比较都不会返回true。