为什么.NET中存在null?

Joa*_*nge 35 .net c# clr performance type-systems

为什么.NET中的值为null?这是否优于保证所有内容都具有值并且没有任何调用为空?

任何人都知道这些方法的名称是什么?

无论哪种方式,我对此都知之甚少,但是在简单性方面,即在消除空检查方面,并且能够编写更加简化的算法而不必分支出来检查.

在性能,简洁性,平行性,面向未来等方面,每种风格的优缺点是什么?

Han*_*ant 37

我们有Tony Hoare,他是Algol的早期先驱,感谢他们.他很后悔:

我称之为十亿美元的错误.它是1965年空引用的发明.那时,我正在设计第一个用于面向对象语言(ALGOL W)的引用的综合类型系统.我的目标是确保所有引用的使用绝对安全,并由编译器自动执行检查.但是我无法抗拒引入空引用的诱惑,仅仅因为它很容易实现.这导致了无数的错误,漏洞和系统崩溃,这可能在过去四十年中造成了数十亿美元的痛苦和损害.

我想,十亿是一个低球数.

  • 啊,很好的参考,但没有`null`s的世界怎么样?你如何终止名单? (4认同)
  • @Henk:并不是说我必须提倡它是一个绝对的,但就像我们使用`Nullable <T>`:一个标志. (4认同)
  • @Joel我100%同意.我甚至在我工作的许多代码库中引入了一个`Maybe <T>`类型.我发现它最终产生了更好的代码. (4认同)
  • @Joel和引擎盖F#实际上使用`null`来实现它的几个构造(特别是选项):) (3认同)
  • @Joan它提供了一种表达引用的声明方式,可以是`null` /不存在.它是以F#选项类型的风格开发的.http://blogs.msdn.com/b/jaredpar/archive/2008/10/08/functional-c-providing-an-option-part-2.aspx (2认同)
  • 我没有看到空指针的发明是如何错误的.有一种标准的方法来定义它是不可能取消引用指针似乎是一个非常好的主意.具有单个可识别空值的指针的运行时成本在许多情况下小于允许更多种类的空值的成本.我看到的关于空指针的唯一设计错误是许多C编译器允许一个索引空指针而不进行陷阱,产生一个无法识别为null的无效指针. (2认同)

Jar*_*Par 24

作为一个没有的世界的吸引力null,它确实给许多现有的模式和结构带来了很多困难.例如,考虑以下构造,如果null不存在则需要进行重大更改

  1. 创建一个引用类型数组ala : new object[42]. 在现有的CLR世界中,阵列将被填充,null这是非法的.数组语义需要在这里改变一下
  2. default(T)仅在T值类型时才有用.不允许在引用类型或无约束泛型上使用它
  3. 需要禁止作为引用类型的结构中的字段.今天可以在CLR中对值类型进行0初始化,这样可以方便地填充引用类型的字段null.这在非null世界中是不可能的,因此类型中的字段是struct中的引用类型将需要被禁止

上述问题都不是无法解决的,但它们确实会导致真正挑战开发人员如何考虑编码的变化.我个人希望C#和.Net的设计是为了消除null,但不幸的是它不是,我想像上面的问题有点与它有关.

  • .NET的大设计支持来自与现有库的兼容.这就是为什么我们有带有结构的指针和值类型,可以直接转换为C中的本机类型.这与java的意识形态略有不同(禁止使用无符号类型和函数指针).这意味着带来null. (3认同)
  • @Joan不幸的是我当时并不在身边,也不知道辩论的细节(如果有的话).Java兼容性是几个设计决策中的一个因素,而我的**猜测**也是围绕"null"做出的决定.但我再一次对此没有任何直接的了解. (2认同)

dth*_*rpe 9

这让我想起詹姆斯伯克的"连线"系列剧集,其中僧侣正在将阿拉伯语转录为拉丁语,并首次遇到零数字.罗马算术没有零的表示,但阿拉伯语/ aramaic算法确实如此."为什么我们要写一封信来表示什么?" 争辩天主教僧侣."如果没什么,我们应该什么都不写!"

幸运的是,对于现代社会来说,他们失去了争论,并学会了在数学中写出零位数.;>

Null只表示没有对象.有些编程语言本身没有"null",但是大多数编程语言仍然有代表缺少合法对象的东西.如果你扔掉"null"并用一个名为"EmptyObject"或"NullNode"的东西替换它,它仍然是一个带有不同名称的null.

如果你删除编程语言表示不引用合法对象的变量或字段的能力,也就是说,你要求每个变量和字段总是包含一个真实有效的对象实例,那么你就做了一些非常有用和有效的数据结构笨拙且效率低下,例如构建链表.程序员不必使用null来指示链表的结尾,而是强制发明"假"对象实例作为列表终端,除了表示"此处没有任何内容"之外什么都不做.

在这里深入探讨存在主义,但是:如果你能代表存在某种东西,那么就没有能够代表它存在的根本需要吗?


小智 6

推测它们存在null于.NET中,因为它(C#)遵循C++/Java脚步(并且在最近的版本中已经开始分支)和VB/J ++(它成为VB.NET/J#)已经存在具有"无"值的概念-也就是说,.NET有null因为什么并没有因为它可能已.

在某些语言中没有概念null - null可以完全替换为类似Maybe的类型 - 有Something(对象)或Nothing(但事实并非如此null!没有办法从Maybe中获取"Nothing" !)

在Scala中使用选项:

val opt = Some("foo") // or perhaps, None
opt match {
   case Some(x) => x.toString() // x not null here, but only by code-contract, e.g. Some(null) would allow it.
   case _ => "nothing :(" // opt contained "Nothing"
}
Run Code Online (Sandbox Code Playgroud)

这是通过 Haskell中的语言设计(null根本不可能!)以及库支持和 Scala中的仔细使用来完成的,如上所示.(Scala支持null- 可以说是Java/C#interop - 但是除非null允许"泄漏",否则可以在不使用此事实的情况下编写Scala代码.

编辑:请参阅Scala:选项模式,Scala:选项作弊CheetSO:在Haskell中使用Maybe Type.大多数时候在Haskell谈论Maybe会带来Monads的主题.我不会声称理解它们,但这里有一个链接以及Maybe的用法.

快乐的编码.


Jul*_*lia 5

好了,现在用C#-without-null包含魔术字

class View
{
    Model model;        

    public View(Model model)
    {
        Console.WriteLine("my model : {0}, thing : {1}", this.model, this.model.thing);
        this.model = model;
    }
}
Run Code Online (Sandbox Code Playgroud)

控制台上印有什么?

  • 抛出没有关于访问未初始化对象的例外:Ok称之为NullReferenceException,那就是当前世界.
  • 它没有构建,用户在声明模型时需要指定一个值,请参阅最后一个项目符号,因为它创建了相同的结果.
  • 一些默认的模型和一些默认的东西:好以前用null我们至少有办法知道一个实例是否正确现在编译器生成奇怪的外观相似,但不包含任何东西,但仍然无效为模型对象...
  • 由对象类型定义的东西:更好,因为我们可以为每个对象定义一个特定的无效状态,但现在每个可能无效的对象需要独立实现它以及调用者识别此状态的方法...

所以基本上对我来说,它似乎没有解决任何东西来删除空状态,因为仍然需要管理可能无效的状态...

哦买的方式接口的默认值是什么?哦,一个抽象类,当在抽象类中定义的默认值上调用方法但是调用另一个抽象方法时会发生什么?.... ....为什么哦为什么一劳永逸地使模型复杂化,这又是多重继承问题!

一种解决方案是完全改变语法以获得一个完整的功能,其中null世界不会退出,只有Maybes,当你希望它们存在时......但它不是一个C语言和多范式的.Net会丢失.

可能缺少的是一个null传播的运算符,model.Thing当模型为null时,它可以返回nullmodel.?.Thing


哦,好好回答你的问题:

  • 当前的类库在Microsoft-Java崩溃之后发展,并且C#被构建为"更好的Java",因此更改类型系统以删除空引用将是一个很大的变化.他们已经设法引入价值类型并删除手动拳击!
  • 正如值类型介绍显示microsoft对速度有很多想法...例如,所有类型的默认值映射到零填充的事实对于快速数组初始化非常重要.否则,初始化参考值数组将需要特殊的威胁.
  • 如果没有null,则不可能与C互操作,因此至少在MSIL级别和不安全的区域中,它们需要被允许存活.
  • 微软希望使用VB6 ++删除框架,Nothing因为在VB中调用它会彻底改变语言,用户从VB6切换到VB.Net需要花费数年的时间,这种范式的改变对语言来说可能是致命的.