我是C ++语言新手,我很难理解允许引用类型为null的原因。
考虑以下代码段
class Person {
private string _name;
public Person(string name) {_name = name;}
void print() {
Console.WriteLine(_name);
}
}
现在没有什么可以阻止呼叫者执行以下操作
Person p = new Person(null);
p.print();
这将崩溃,如果将null传递给构造函数,我可以通过抛出异常来维护(不是真的),但这只是意味着如果没有捕获它,我会在第一行崩溃(我无法在C#中强制AFAIK ),而不是第二行。
调用者必须阅读文档(这意味着我不能忘记记录构造函数可能抛出的文档)以了解所有这些信息。
答案 0 :(得分:2)
(允许)语言允许空引用的原因是什么 类型?
我可能在纸上有一个盒子,上面写着“谁是没有眼睛的男人?”的答案。我没有这个问题的答案,所以我将方框留空。空白框对此无反应,着火并用力……只是按预期保持空白。
什么时候有利,而不仅仅是定时炸弹?唯一的那个 我能想到的是惰性初始化,想分配一个 有条件的对象。
我具有可以处理“没有眼睛的男人”的功能,但是,有时候男人不存在。我可能会发现这些情况并做出不同的反应。
我该如何在编写的代码中处理这个问题?
空检查。欢迎来到2018年,您c ++裸机专家有 alot 可以学习。这是您已经知道的东西,但是这些知识存在于其他地方,直到现在似乎都没有意义。
答案 1 :(得分:2)
语言允许使用空引用类型的原因是(有可能)是什么?
有时候您想要的东西不具有价值。例如,考虑具有父子关系的节点类。如果Parent
永远不能为null,那将是非常不愉快的。甚至在C ++中,指针也可以指向“无”,例如0
。
我该如何在编写的代码中处理这个问题?
从第一天开始就一直是一个问题。C#团队一直希望我们作为开发人员通过进行足够的null检查来“解决”此问题。这就是我们一直在做的。
现在,在C#8(仍在开发中)中,有nullable reference types。启用后,如果将可能不为null的变量分配为null或可能为null,则会出现编译器错误。
答案 2 :(得分:1)
如果我们反问...
由于您来自C ++,因此我们可以问“ C ++如何摆脱不能为null的引用”。简单的答案是“嗯,它具有空指针,因此它不需要空引用”。具有两种不同类型的变量来表示对对象的引用(具有不同的规则和语法),这使得C ++ 非常简单。
是的,Tony Hoare声称空引用是他的“十亿美元的错误”。但是,如果您没有一种方法来表示未分配的引用,则很难使用简单的语法来获得可用的C系列语言。
考虑以下简单的C#代码:
string myString;
if (condition) {
myString = func1();
} else {
mystring = func2();
}
UseTheString(myString);
必须在外部范围中声明字符串变量。如果每个引用变量都需要在声明时进行初始化(例如C ++引用),那么您需要使用一些会被扔掉几行的东西来对其进行初始化。是的,您可能会说,这就是string.Empty
的目的。比System.String更复杂的类型呢-构造起来更昂贵的类型呢?他们是否都需要一个unassigned
值;越来越接近null
。嘿,JavaScript既有(null也有未分配的)!
C ++参考非常方便,但它们也非常有约束力。在声明它们时,不仅必须为其分配某些内容,而且它们也是不可变的(变量-而不是它们所引用的对象)。声明并初始化C ++引用后,您将无法更改其引用的内容。如果C#引用遵循此规则,则下面的代码将很有趣(忽略这样的事实:循环中的字符串连接几乎总是一个坏主意):
string myString = string.Empty;
for (var i = 0; i < someValue; ++i) {
myString = myString + SomeFunc(i);
}
然后,有些事情自然会被考虑为空,例如关系数据库中的可为空的东西。可以为空的值类型(Nullable<T>
)出现在框架的第一个主要后继版本中也就不足为奇了。我们很多人都记得(而且我们中有些人仍在应付)DbNull类型(和值)的痛苦。
是的,应付空值是一种痛苦。大多数(但不是全部)语言中都有它。 C#语言(具有引用类型和值类型的组合,共享一种变量语法)比C ++易于阅读/理解/提取。我发现与使用C ++程序员相比,用C#编写的错误更少(尽管,在最近对语言进行所有更改之前,我是90年代的C ++程序员)。
C#8.0的人们认为他们有一个解决方案(这不是完整的解决方案,但是它应该使空引用异常更加少见)。我很好奇您对C#如何避免Hoare博士的数十亿美元错误的想法。
答案 3 :(得分:0)
这样null
不会被用作值。
class Program
{
static void Main(string[] args)
{
Person person = new Person(null);
person.PrintName();
}
}
class Person
{
private string Name { get; set; }
public Person(string name)
{
this.Name = name ?? "My name can't be null";
}
public void PrintName()
{
Console.WriteLine(this.Name);
}
}