为什么人们在代码中使用魔术值而不是null?

Pac*_*aco 9 magic-numbers

我在遗留代码和一些.NET开源项目中看到了这一点.我无法想象这样做的理由.只使用"null"对我来说似乎更容易.

例:

public class Category
{
   int parentID;

   bool HasParent
   {
      get
      {
          return parentID != -1;
      }
   }
}
Run Code Online (Sandbox Code Playgroud)

public class Category
{
   int parentID;

   bool HasParent
   {
      get
      {
          return parentID != null;
      }
   }
}
Run Code Online (Sandbox Code Playgroud)

Dav*_*vid 11

因为要具有"null"值,所以类型必须是可空的.这适用于引用类型(您定义的任何类和标准库),如果您看起来您将看到人们没有值的引用对象时确实使用null

Employee employee = Employees.Find("John Smith");
if(employee == null) throw new Exception("Employee not found");
Run Code Online (Sandbox Code Playgroud)

当您使用int,char或float 等值类型时会出现问题.与引用类型不同,引用类型指向内存中其他位置的数据块,这些值是内联存储和操作的(没有指针/引用).

因此,默认情况下,值类型不具有空值.在您提供的代码中,parentID 不可能为null(我甚至对您的编译器实际上感到惊讶 - Visual Studio 2008,可能2005年将绘制绿色下划线并告诉您该语句始终为false).

为了使int具有null值,您需要将其声明为可为空

int? parentID;
Run Code Online (Sandbox Code Playgroud)

现在 parentID可以包含一个空值,因为它现在是一个32位整数的指针(井"引用"),而不是一个32位整数.

所以希望你理解为什么"魔术值"经常被用来用基本类型(值类型)来表示null.这只是一个很麻烦的事情,通常会有很大的性能损失(查找装箱/拆箱的内容),将这些值类型存储为值的引用,以便允许它们为空.

编辑:有关装箱/拆箱(你需要有一个int == null)的进一步参考,请参阅MSDN上的文章:

拳击和拆箱(C#编程指南)

性能

与简单分配相关,装箱和拆箱是计算上昂贵的过程.装箱值类型时,必须分配和构造新对象.在较小程度上,拆箱所需的演员阵容在计算上也是昂贵的.有关更多信息,请参阅性能.

  • 开销是*不小* - 您正在谈论为*基金*数据类型和操作添加装箱/拆箱操作.由于装箱开销,当值可以为空时,执行条件整数加法运算的基准测试运行速度慢9倍.亲自试试吧. (2认同)

And*_*are 0

您是否真正研究过该应用程序?只要将神奇数字保存在一个位置并具有描述性名称,它就会非常有用。