2 回答
TA贡献1829条经验 获得超4个赞
该语言允许空引用类型的(可能)原因是什么?
有时你想要一些没有价值的东西。例如,考虑具有父子关系的节点类。如果Parent
永远不能为空,那将是非常不愉快的。即使在 C++ 中,指针也可以指向“无”,如0
.
我如何在我编写的代码中处理这个问题?
从第一天起这就是一个问题。C# 团队一直希望我们作为开发人员通过进行足够的空检查来“修复”这个问题。这就是我们一直在做的事情。
现在,在 C# 8(仍在开发中)有可以为null 的引用类型。启用后,如果将可能不为 null 的变量分配为 null 或可能为 null,您将收到编译器错误。
TA贡献1828条经验 获得超6个赞
如果我们把问题反过来...
由于您来自 C++,我们可以问“C++ 如何摆脱不能为空的引用”。简单的答案是“好吧,它有空指针,所以它不需要空引用”。有两种不同类型的变量来表示对对象的引用(具有非常不同的规则和语法)使 C++变得更加简单。
是的,Tony Hoare声称空引用是他的“数十亿美元的错误”。但是,如果您无法表示未分配的引用,则很难使用简单的语法获得可工作的 C 系列语言。
考虑这个简单的 C# 代码:
string myString;
if (condition) {
myString = func1();
} else {
mystring = func2();
}
UseTheString(myString);
字符串变量必须在外部作用域中声明。如果每个引用变量都需要在声明时初始化(如 C++ 引用),那么您需要使用一些会被丢弃几行的东西来初始化它。是的,你可能会说,这就是为什么string.Empty。比 System.String 更复杂的类型 - 构造成本更高的类型呢?他们是否需要都具有unassigned价值?这已经非常接近了null。嘿,JavaScript 有(空值和未赋值)!
C++ 引用非常方便,但它们也很受限制。它们不仅在声明时必须被赋值,而且它们也是不可变的(变量 - 而不是它们引用的对象)。一旦声明并初始化 C++ 引用,就无法更改它所引用的内容。如果 C# 引用遵循此规则,则编写下面的代码会很有趣(忽略循环中的字符串连接几乎总是一个坏主意的事实):
string myString = string.Empty;
for (var i = 0; i < someValue; ++i) {
myString = myString + SomeFunc(i);
}
然后,需要考虑一些自然为空的内容,例如关系数据库中可为空的内容。可空值类型 ( Nullable<T>) 出现在框架的第一个主要发布 v1 版本中也就不足为奇了。我们很多人都记得(我们中的一些人仍然在应付) DbNull 类型(和值)的痛苦。
是的,处理空值是一种痛苦。大多数(但不是全部)语言中都有它。C# 语言(引用类型和值类型的组合共享一个变量语法)比 C++ 更容易阅读/理解/挑选。我发现我在 C# 中编写的错误比作为 C++ 程序员少得多(不过,在最近对语言进行所有更改之前,我是 90 年代的 C++ 程序员)。
C# 8.0 人员认为他们有一个解决方案(这不是一个完整的解决方案,但它应该使空引用异常更加罕见)。我很好奇您对 C# 如何避免 Hoare 博士的十亿美元错误的看法。
- 2 回答
- 0 关注
- 174 浏览
添加回答
举报