默认字符串初始化:NULL还是Empty?

时间:2008-11-05 17:08:01

标签: c#

我总是将我的字符串初始化为NULL,认为NULL表示缺少值,而“”或String.Empty是有效值。我最近看到了更多代码示例,其中String.Empty被视为默认值或不表示任何值。这让我很奇怪,在c#中新添加的可空类型似乎我们通过不使用NULL来表示“无值”来向后移动字符串。

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

编辑:基于答案,我进一步思考

  1. 避免错误处理如果该值不应为null,为什么它首先设置为NULL?也许最好在发生错误的位置识别错误,而不是在代码库的其余部分覆盖错误?

  2. 避免空检查如果您厌倦了在代码中进行空检查,那么抽象空检查是不是更好?也许包装(或扩展!)字符串方法使它们NULL安全吗?如果您经常使用String.Empty并且null正好进入系统会发生什么情况,那么您是否开始添加NULL检查?

  3. 我忍不住回到懒惰的意见。如果你在他的数据库中使用''而不是null,那么任何DBA都会狠狠地打你九种方式。我认为相同的原则适用于编程,并且应该有人利用String.Empty而不是NULL来代表没有价值的头脑。

      

    相关问题

         

17 个答案:

答案 0 :(得分:110)

+1用于区分“空”和NULL。我同意“空”应该表示“有效,但空白”,“空”应表示“无效”。

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

当我想要一个可能会或可能不会更改的有效默认值时,

为空,例如,用户的中间名。

NULL 如果后续代码没有明确设置值,则会出错。

答案 1 :(得分:30)

根据MSDN

  

通过使用Empty值而不是null初始化字符串,可以减少NullReferenceException发生的可能性。

尽管如此,始终使用IsNullOrEmpty()是一种很好的做法。

答案 2 :(得分:13)

为什么要对字符串进行初始化?在声明变量时,您不必初始化变量,而IMO,只有当您分配的值在代码块的上下文中有效时才应该这样做。

我看到了很多:

string name = null; // or String.Empty
if (condition)
{
  name = "foo";
}
else
{
  name = "bar";
}

return name;

不初始化为null同样有效。此外,通常您需要分配值。通过初始化为null,您可能会错过未分配值的代码路径。像这样:

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

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

Matthijs

答案 3 :(得分:8)

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

if (s == "value")

我感觉很糟糕。为什么这个方法中有字符串文字?设置s是什么?它知道逻辑取决于字符串的值吗?是否知道必须小写才能工作?我应该通过将其更改为使用String.Compare来解决此问题吗?我应该创建一个Enum并解析它吗?

从这个角度来看,人们可以使用非常简单的代码哲学:尽可能避免检查字符串的内容。将字符串与String.Empty进行比较实际上只是将其与文字进行比较的特殊情况:除非您真的需要,否则应该避免这样做。

知道了这一点,当我在代码库中看到类似内容时,我不会眨眼:

string msg = Validate(item);
if (msg != null)
{
   DisplayErrorMessage(msg);
   return;
}

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

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

(只是为了确保我不是说我的屁股,我只是寻找我们的代码库`String.IsNullOrEmpty”。所有54个出现的是它的方法处理用户输入,从Python脚本返回值,检查从外部API等检索的值。)

答案 4 :(得分:5)

取决于。

您是否需要能够判断该值是否丢失(是否可能无法定义)?

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

如果您对两者都回答“是”,那么您将要使用null。否则你无法区分“无值”和“空字符串”之间的区别。

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

答案 5 :(得分:5)

这实际上是C#语言中的一个漏洞。无法定义不能为null的字符串。这会导致问题像您所描述的那样简单,这迫使程序员做出他们不应该做出的决定,因为在很多情况下,NULL和String.Empty意味着相同的事情。反过来,这可能会迫使其他程序员必须同时处理NULL和String.Empty,这很烦人。

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

其他语言,例如Spec#,确实允许这样做。

在我看来,C#无法定义不允许null的字符串与之前无法定义允许null的int一样糟糕。

完全回答你的问题:我总是使用空字符串进行默认初始化,因为它更类似于数据库数据类型的工作方式。 (编辑:这个陈述非常不清楚。它应该是“我使用空字符串进行默认初始化,当NULL是一个多余的状态时,就像我将数据库列设置为NOT NULL一样,如果NULL是一个多余的状态。” ,我的许多数据库列都设置为NOT NULL,所以当我将它们带入C#字符串时,字符串将为空或具有值,但永远不会为NULL。换句话说,我只将字符串初始化为NULL如果null的含义与String.Empty的含义不同,我发现这种情况不常见(但这里的人已经给出了这种情况的合法例子)。“)

答案 6 :(得分:4)

答案 7 :(得分:3)

我要么将它设置为“”或null - 我总是使用String.IsNullOrEmpty来检查,所以要么很好。

但是我内心的极客说我应该把它设置为null才能得到适当的价值......

答案 8 :(得分:3)

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

答案 9 :(得分:2)

这可能是一种错误避免技术(建议与否......)?由于“”仍然是一个字符串,你可以在其上调用字符串函数,如果它是NULL,会导致异常吗?

答案 10 :(得分:2)

我始终将其初始化为 NULL

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

简单。

答案 11 :(得分:1)

这取决于具体情况。在大多数情况下,我使用String.Empty,因为每次尝试使用字符串时我都不想进行空检查。它使代码更简单,并且不太可能引入不需要的NullReferenceException崩溃。

当我需要知道它是否已经设置时,我只将字符串设置为null,并且空字符串是设置为有效的字符串。在实践中,我发现这些情况很少见。

答案 12 :(得分:1)

Null仅应在值为可选的情况下使用。如果该值不是可选的(例如'名称'或'地址'),则该值永远不应为null。这适用于数据库以及POCO和用户界面。 Null表示"此值是可选的,目前不存在。"

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

我个人认为默认情况下字符串不可为空,但如果我们声明一个"字符串,那么它只能是可空的?"。虽然这可能在更深层次上不可行或合乎逻辑;不确定。

答案 13 :(得分:1)

重申Tomalak响应,请记住,当您将字符串变量分配给初始值null时,您的变量不再是字符串对象;与C#中的任何对象相同。因此,如果您尝试访问变量的任何方法或属性,并且假设它是一个字符串对象,您将获得NullReferenceException异常。

答案 14 :(得分:1)

空字符串是一个值(一个文本,顺便说一下,不包含任何字母)。 Null表示无价值。

当我想表明它们没有指向或包含实际值时,我将变量初始化为null - 当意图是无值时。

答案 15 :(得分:0)

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

答案 16 :(得分:0)

我认为没有理由不将null用于未分配(或在程序流中未出现的位置)值。 如果你想区分,那么== null。 如果你只想检查某个值并且不关心它是否为null或者不同,String.Equals(“XXX”,MyStringVar)就可以了。