代码之家  ›  专栏  ›  技术社区  ›  arynaq

引用类型超出空值的基本原理[关闭]

c#
  •  1
  • arynaq  · 技术社区  · 8 年前

    考虑下面的片段

    class Person {
      private string _name;
      public Person(string name) {_name = name;}
    
      void print() {
        Console.WriteLine(_name);
      }
    }
    

    现在没有什么可以阻止来电者执行以下操作

    Person p = new Person(null);
    p.print();
    

    调用者必须阅读文档(这意味着我不能忘记记录构造函数可能抛出的文档)才能知道所有这些。

    • 语言允许空引用类型的原因是什么?
    • 在我编写的代码中如何处理这个问题?
    4 回复  |  直到 8 年前
        1
  •  2
  •   Davesoft    8 年前

    语言允许空引用的原因是什么 类型?

    我可能会在一张纸上放一个盒子,用来写“谁是没有眼睛的人?”。我没有那个问题的答案,所以我把方框留空。空白的盒子对这个没有反应,着火,强迫我的手。。。它只是保持空白,正如预期的那样。

    什么时候这是有利的,而不仅仅是一个定时炸弹?那个 有条件地反对。

    在我编写的代码中如何处理这个问题?

    空支票。欢迎来到2018,你们这些c++裸机的家伙

        2
  •  2
  •   Patrick Hofman Wahid Bitar    8 年前

    有时候你想要什么 Parent 不能为空。即使在C++中,指针也可以指向“没有”,如 0 .

    从第一天开始这就成了问题。C团队总是希望我们作为开发人员通过足够的空检查来“修复”这个问题。这就是我们一直在做的。

    nullable reference types . 启用时,如果将可能不为空的变量指定为空或可能为空,则会出现编译器错误。

        3
  •  1
  •   Flydog57    8 年前

    既然你来自C++,我们可以问“C++如何摆脱那些不能为空的引用”。简单的答案是“它有空指针,所以不需要空引用”。有两种不同的变量,它们表示对象的引用(具有非常不同的规则和语法),使得C++ 这么多

    对, Tony Hoare

    考虑一下这个简单的C代码:

    string myString;
    if (condition) {
        myString = func1();
    } else {
        mystring = func2();
    }
    UseTheString(myString);
    

    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#8.0的人认为他们有一个解决方案(这不是一个完整的解决方案,但它应该使空引用异常更加罕见)。我很好奇你对C#如何避免霍尔博士数十亿美元的错误有什么想法。

        4
  •  0
  •   Marco Salerno    8 年前

    这种方式 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);
        }
    }