关于c#:默认字符串初始化:NULL还是Empty?


Default string initialization: NULL or Empty?

我总是将字符串初始化为空,认为空意味着没有值,"or string.empty"是有效值。我最近看到了更多的代码示例,其中string.empty被认为是默认值或不代表任何值。这让我觉得很奇怪,在C中新增了可以为空的类型,我们似乎在用字符串向后跨步,不使用空来表示"无值"。

您使用什么作为默认初始值设定项?为什么?

编辑:根据答案,我进一步思考

  • 为了避免错误处理,如果值不应为空,为什么首先将其设置为NULL?也许最好是在错误发生的地方识别它,而不是通过代码库的其余部分来掩盖它?

  • 如果您厌倦了在代码中执行空检查,那么避免空检查是不是更好地抽象空检查?可能是包装(或扩展!)字符串方法使它们NULL安全吗?如果你经常使用String.Empty,而一个空值恰好以这种方式工作在你的系统中,你会怎么办?你是否开始添加NULL检查?

  • 我忍不住又回到了那种认为这是懒惰的观点。如果您在数据库中使用""而不是NULL,任何DBA都会给您九种愚蠢的方法。我认为同样的原则也适用于编程,应该有人用String.Empty而不是NULL来表示没有价值的东西来打那些头。

    Related Questions

    • In C#, should I use string.Empty or String.Empty or"" ?
    • What is the difference between String.Empty and""
    • Null or empty string to represent no data in table column?


    +1用于区分"空"和空。我同意"空"是指"有效,但空白"和"空"是指"无效"。

    所以我会这样回答你的问题:

    当我需要一个可以更改或不可以更改的有效默认值时为空,例如,用户的中间名。

    如果后续代码未显式设置值,则为空。


    根据msdn:

    By initializing strings with the Empty value instead of null, you can reduce the chances of a NullReferenceException occurring.

    不过,始终使用IsNullOrEmpty()是一种很好的做法。


    为什么要初始化字符串?声明变量时不必初始化变量,而imo,应该只在所分配的值在代码块上下文中有效时才初始化变量。

    我经常看到:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    string name = null; // or String.Empty
    if (condition)
    {
      name ="foo";
    }
    else
    {
      name ="bar";
    }

    return name;

    不初始化为空也同样有效。此外,通常您希望分配一个值。通过初始化为空,您可能会错过没有赋值的代码路径。像这样:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    string name = null; // or String.Empty
    if (condition)
    {
      name ="foo";
    }
    else if (othercondition)
    {
      name ="bar";
    }

    return name; //returns null when condition and othercondition are false

    如果不初始化为空,编译器将生成一个错误,说明并非所有代码路径都分配一个值。当然,这是一个非常简单的例子…

    马蒂耶斯


    对于大多数实际上不是字符串处理软件的软件,程序逻辑不应该依赖于字符串变量的内容。每当我在程序中看到类似的东西时:

    1
    if (s =="value")

    我感觉不好。为什么这个方法中有字符串?什么设置了s?它知道逻辑依赖于字符串的值吗?它知道工作必须是低级别的吗?我应该改成使用String.Compare来解决这个问题吗?我应该创建一个Enum并解析它吗?

    从这个角度来看,代码的哲学非常简单:尽可能避免检查字符串的内容。将一个字符串与String.Empty进行比较,实际上只是将其与文字进行比较的一个特例:除非确实需要,否则必须避免这样做。

    知道了这一点,当我在我们的代码库中看到这样的东西时,我不会眨眼:

    1
    2
    3
    4
    5
    6
    string msg = Validate(item);
    if (msg != null)
    {
       DisplayErrorMessage(msg);
       return;
    }

    我知道Validate永远不会返回String.Empty,因为我们编写的代码比这更好。

    当然,世界上其他地方的情况并不是这样的。当您的程序处理用户输入、数据库、文件等时,您必须考虑其他哲学。在那里,你的代码的工作就是在混乱中强加秩序。该顺序的一部分是知道空字符串何时表示String.Empty,何时表示null

    (为了确保我不是在胡说八道,我只是在代码库中搜索了"string.isnullorempty"。所有54次出现在处理用户输入、从Python脚本返回值、检查从外部API检索的值等方法中。)


    这实际上是C语言中的一个漏洞。无法定义不能为空的字符串。这导致了和您描述的问题一样简单的问题,这迫使程序员做出他们不应该做的决定,因为在许多情况下,空和字符串都是一样的。反过来,这又会迫使其他程序员必须同时处理空值和string.empty,这很烦人。

    更大的问题是,数据库允许您定义映射到C字符串的字段,但数据库字段可以定义为非空。因此,在使用C类型的SQL Server中,无法准确地表示varchar(100)非空字段。

    其他语言,如spec,也允许这样做。

    在我看来,C无法定义不允许为空的字符串,与它以前无法定义不允许为空的in t一样糟糕。

    要完全回答您的问题:我总是使用空字符串进行默认初始化,因为它更类似于数据库数据类型的工作方式。(编辑:这份声明非常不清楚。它应该读到"当空值是多余状态时,我使用空字符串进行默认初始化,这与我设置数据库列为非空值的方式非常相似,如果空值是多余状态的话。同样,我的许多DB列都设置为非空,因此当我将它们放入C字符串时,该字符串将为空或具有值,但永远不会为空。换句话说,只有当空值的含义与string.empty的含义不同时,我才将字符串初始化为空值,并且我发现该大小写不常见(但这里的人们给出了这种情况的合法示例)。")


    这要看情况而定。

    您是否需要能够判断值是否丢失(是否可以不定义)?

    空字符串是否为该字符串的有效使用值?

    如果您对两者都回答"是",那么您将希望使用空值。否则就不能分辨"无值"和"空字符串"的区别。

    如果您不需要知道是否没有值,那么空字符串可能更安全,因为它允许您在任何使用它的地方跳过空检查。


    似乎这是http://en.wikipedia.org/wiki/null_object_模式的一个特例。


    我要么将其设置为"或空-我总是使用string.isNullOrEmpty进行检查,所以两者都可以。

    但我内心的极客说,在我有一个合适的值之前,我应该把它设置为空…


    我总是用string.empty声明字符串;


    我总是把它们初始化为null

    我总是用string.IsNullOrEmpty(someString)来检查它的价值。

    简单。


    这是否可能是一种避免错误的技术(建议还是不建议….)?因为"仍然是一个字符串,所以您可以对它调用字符串函数,如果它为空,则会导致异常?


    这取决于情况。在大多数情况下,我使用string.empty,因为我不希望每次尝试使用字符串时都进行空检查。它使代码更简单,并且您不太可能导致不需要的nullreferenceexception崩溃。

    我只在需要知道字符串是否已设置以及空字符串在何处有效时才将其设置为空。实际上,我发现这种情况很少见。


    空字符串是一个值(顺便说一下,一段文本恰好不包含任何字母)。空表示没有值。

    当我希望指示变量不指向或不包含实际值时,我将变量初始化为空值-当目的是不指向任何值时。


    重申tomalak响应,请记住,当您将字符串变量赋给初始值为空时,您的变量不再是字符串对象;与C中的任何对象相同。因此,如果您试图访问变量的任何方法或属性,并且假设它是字符串对象,那么您将得到NullReferenceException异常。


    空值只能在值为可选的情况下使用。如果该值不是可选的(如"name"或"address"),则该值不应为空。这适用于数据库、POCO和用户界面。空表示"此值是可选的,当前不存在。"

    如果字段不是可选的,则应将其初始化为空字符串。若要将其初始化为空,将使对象处于无效状态(由您自己的数据模型无效)。

    就我个人而言,我希望字符串在默认情况下不可以为空,而只在声明"string"时才可以为空。虽然这在更深层次上可能不可行或不合理;不确定。


    我认为没有理由不为未分配的(或者在程序流中的这个地方没有发生)值使用空值。如果要区分,有==空。如果您只想检查某个值,而不关心它是空值还是其他值,那么string.equals("xxx",mystringvar)就可以了。


    字符串不是值类型,永远不会是;-)