C# null的显式赋值

C# null的显式赋值,c#,C#,我真的不明白为什么需要明确的任务。空变量和未赋值变量之间有什么区别?我总是假设运行时/编译器只是简单地将未分配的变量分配为null。如果它们不是null,那么它们是什么?C编译器不允许使用未初始化的局部变量。初始未分配的变量没有初始值。未分配的成员将自动初始化为其默认值(在字符串的情况下为空引用) 未分配的局部变量未分配任何值,尝试访问可能未分配的变量将导致编译错误。需要显式分配的原因非常简单。当人们试图使用未分配/未初始化的变量时,这通常是错误的来源 通过强制开发人员这样做,它消除了开发人员忘

我真的不明白为什么需要明确的任务。空变量和未赋值变量之间有什么区别?我总是假设运行时/编译器只是简单地将未分配的变量分配为null。如果它们不是null,那么它们是什么?

C编译器不允许使用未初始化的局部变量。初始未分配的变量没有初始值。

未分配的成员将自动初始化为其默认值(在
字符串的情况下为空引用)


未分配的局部变量未分配任何值,尝试访问可能未分配的变量将导致编译错误。

需要显式分配的原因非常简单。当人们试图使用未分配/未初始化的变量时,这通常是错误的来源

通过强制开发人员这样做,它消除了开发人员忘记初始化变量时发生的错误。通过初始化它,你就能控制它

这真是件好事!我不知道我在一些脚本语言中有多少未初始化或未定义的变量,这需要花费相当长的时间才能找到^^

  • 如果你有一个未赋值的局部值,你很可能在做一些愚蠢的事情。更糟糕的是,你正在做一件聪明人在最热的时候可以做的蠢事(每个人每天都做蠢事)

  • 与某些导致警告的情况不同,在特定情况下使用未赋值值没有可能的优势

  • 允许未分配的本地值或假定特定值之间的唯一成本差异是几次击键(通常
    =null;
    最多可以是
    =default(SomeType);

  • 禁止这种构造的好处多,坏处少。没有技术上的原因说明该语言不能被设计为允许未分配的局部变量,但是禁止的好处大于缺点。

    看看规范:

    在以下情况下,明确分配是一项要求:
    必须在获得变量值的每个位置明确指定变量

    s1和s2最初是未分配的(),但只有s2被认为是在给定位置上明确分配的,[因为]通向该位置的所有可能执行路径至少包含以下一个:

    • 一种简单赋值(第7.13.1节),其中变量是左操作数

    正如您所看到的,null在这种情况下是不相关的。重要的是赋值本身,而不是值。

    从未赋值的变量拥有一个未定义的值。在最坏的情况下,这在大多数语言中实际发生,这意味着它可以有任何值,因为它解决了一些内存位,这很可能以前被用于另一个目的,甚至可能被另一个程序使用。一些语言确保所有变量都被初始化为一些合理的默认值。然而,这可能只是一种浪费,因为最终这是一个写操作,可能不是必需的,默认情况下这样做是浪费时间。

    需要记住的一点是,作用域将在其中发挥作用。如果您将S1定义为类变量,然后在函数中对其进行测试,则编译器不会停止,代码也会正常运行。原因是,在实例化类时,变量已初始化

    在方法内部移动,很可能在初始化变量之前测试变量时忘记了什么


    我看到的另一个警告是字符串的默认值是什么?(更重要的是在一个不会改变的规范中?请记住,空字符串与空赋值字符串不同。但是有一种方法可以解决这个问题,因为您可以改为使用string.IsNullOrEmpty(S1)进行测试。

    那么“无值”之间的区别是什么还有空值?@FearofahackPlanet:
    无值
    是指变量
    声明
    但未定义
    。不存在的东西不能有值。定义变量时,默认情况下或赋值时,它可以有空值。@Mike:它确实存在。在某个地方为该变量留出了空间。C#had一个选择:默认情况下分配空间
    null
    ,然后继续,或者强迫你自己把
    null
    放在那里。我看不出后一种方法有什么好处。C#不允许使用未分配的局部变量。字段、数组元素、形式参数、指针解引用等都被认为是无效的“出生时分配“原来如此。@Eric,谢谢,我在回答中添加了形容词local。值得注意的是,编译器相对容易确定未分配局部变量,而成员或全局变量则非常困难。因此,行为上存在差异。没有任何东西被分配给null。某些东西可以分配为null:)@martineau:C#@Winston中没有全局变量,这不仅仅是非常困难的,通常是不可能的。:(参见停止问题)顺便说一句,发生这种情况的原因是编译器很有帮助。此错误消息允许编译器帮助您查找大量错误,否则您可能会错过这些错误。理解——不要在第一次传递时将变量初始化为null。编写不需要赋值的代码,看看你是否真的需要它,如果你不能轻松地重写你的代码而不需要赋值,那么继续添加它,但永远不要养成自动赋值的习惯。在Python中,你必须赋值初始值。你不能只说
    a
    ,你必须说
    a=None
    或别的什么。在JS中,你可以做
    varx但这意味着
    var x=未定义,仍在为其赋值。我看不出这个Java是如何运行的
    
    string s1;
    string s2 = null;
    
    if (s1 == null) // compile error
    if (s2 == null) // ok