9

我在遗留代码和一些 .NET 开源项目中看到了这一点。我想不出这样做的理由。仅使用“null”对我来说似乎要容易得多。

例子:

public class Category
{
   int parentID;

   bool HasParent
   {
      get
      {
          return parentID != -1;
      }
   }
}

相对

public class Category
{
   int parentID;

   bool HasParent
   {
      get
      {
          return parentID != null;
      }
   }
}
4

6 回答 6

11

Because to have a "null" value, the type must be nullable. This works fine for reference types (any class you define and the standard library), and if you look you'll see that people do use null whenever they have a reference object with no value

Employee employee = Employees.Find("John Smith");
if(employee == null) throw new Exception("Employee not found");

The issue comes when you use the value types like int, char or float. Unlike reference types, which point to a block of data somewhere else in memory, these values are stored and manipulated inline (there is no pointer/reference).

Because of this, by default, the value types do not have a null value. In the code you provided, it is impossible for parentID to be null (I'm actually surprised this even got by your compiler - Visual Studio 2008 and probably 2005 will draw a green underline and tell you that the statement is always false).

In order for an int to have a null value, you need to declare it as nullable

int? parentID;

Now parentID can contain a null value, because it is now a pointer (well "reference") to a 32 bit integer, instead of just a 32bit integer.

So hopefully you understand why "magic values" are often used to represent null with the basic types (value types). It is simply a lot of trouble, and often a large performance hit (lookup what boxing/unboxing is), to store these value types as a reference to the value in order to allow them to be null.

Edit: For further reference about boxing/unboxing (what you need to have an int==null), see the article at MSDN:

Boxing and Unboxing (C# Programming Guide)

Performance

In relation to simple assignments, boxing and unboxing are computationally expensive processes. When a value type is boxed, a new object must be allocated and constructed. To a lesser degree, the cast required for unboxing is also expensive computationally. For more information, see Performance.

于 2009-02-26T17:48:23.917 回答
4

这些通常是用 C 编程时养成的习惯。许多 C 程序员会对可空 int 的浪费感到震惊,这至少需要一个完整的额外位,甚至可能需要一个指针。当您知道该值将是正值并且您有整个负值空间可用于标志时,这尤其糟糕。-1 可能表示未设置,-2 可能表示 parentId 在此节点的上下文中甚至没有意义,-3 可能表示该节点的父节点无法处理工作并继续酗酒,并且再也见不到了,等等……

在 C# 世界中,可空整数(以及它们与 RDMS 的轻松集成)以及具有 2GB+ RAM 的计算机的清洁意味着旧的 C 习惯正在慢慢消失,但旧的习惯很难改掉。

于 2009-02-26T17:24:07.547 回答
3

拥有一个空对象可能会引发异常,而错误代码(如“-1”失败案例)不会引发异常。

这在不能很好地处理异常的语言或应用程序中可能很关键。

于 2009-02-26T16:49:07.350 回答
2

在大数据仓库工作时,我有时使用 0 值而不是 null,在我的多维数据集中插入一个非 null 值。我总是有一个 0 id 对应于所有维度的“未知”值,所以我有一个没有空值的多维数据集。

它的主要兴趣是有更简单和更有效的查询

于 2009-02-26T16:51:03.510 回答
1

可空值类型并非在每种语言/环境中都可用;它们被添加到 .Net 2.0。如果您的旧代码是基于 .Net 的并且是使用 1.1 框架开始的,那么您的答案是 null 当时不是一个选项。

于 2009-02-26T17:32:37.090 回答
0

您是否真的查看了应用程序以查看?只要将幻数保存在一个带有描述性名称的地方,它就会非常有用。

于 2009-02-26T16:48:12.173 回答