繁体   English   中英

为什么我不总是在C#中使用可为空的类型

[英]Why shouldn't I always use nullable types in C#

自从.net 2.0中引入此概念以来,我一直在寻找有关此问题的良好指导。

为什么我要在c#中使用不可为空的数据类型? (一个更好的问题是,为什么我默认情况下不选择可空类型,而只在明确有意义的情况下才使用非空类型。)

选择非空对等数据类型的可空数据类型是否会对性能产生重大影响?

我更喜欢针对null而不是Guid.empty,string.empty,DateTime.MinValue,<= 0等检查我的值,并且通常使用可为null的类型。 我不经常选择可为空的类型的唯一原因是我的后脑发痒,这让我感觉不仅仅是向后兼容会导致额外的“?” 字符,以明确允许空值。

有没有人总是(最经常)选择可空类型而不是非可空类型?

谢谢你的时间,

之所以不总是使用可为空的类型,是因为有时您可以保证初始化一个值。 而且,您应该尝试设计代码,以便尽可能多地出现这种情况。 如果无法对值进行初始化,则没有理由为什么null应该是合法值。 作为一个非常简单的示例,请考虑以下问题:

List<int> list = new List<int>()
int c = list.Count;

始终是有效的。 没有任何可能的方法可以初始化c 如果它变成一个int? ,您实际上会告诉代码的读者“此值可能为null。使用前请务必进行检查”。 但是我们知道这永远不会发生,那么为什么不在代码中公开这种保证呢?

如果值是可选的,那么您绝对正确。 如果我们有一个可能会或可能不会返回字符串的函数,则返回null。 不要返回string.Empty()。 不要返回“魔术值”。

但并非所有值都是可选的。 并且使所有内容都可选,使其余代码变得更加复杂(它增加了另一个必须处理的代码路径)。

如果可以明确保证此值始终有效,那么为什么要丢弃此信息呢? 这就是使它成为可为空的类型的方法。 现在,该值可能存在或不存在,并且使用该值的任何人都必须处理这两种情况。 但是您知道,首先这些情况只有一种可能。 您的代码用户也是如此,并在您的代码中反映这一事实。 然后,您的代码的任何用户都可以依靠该值是否有效,而他们只需要处理一个个案而不是两个个案。

因为总是必须检查可空类型是否为null这很不方便。

显然,在某些情况下,值是真正可选的,在这种情况下,使用可为空的类型而不是幻数是有意义的,但是在可能的情况下,我会尽量避免使用它们。

// nice and simple, this will always work
int a = myInt;

// compiler won't let you do this
int b = myNullableInt;

// compiler allows these, but causes runtime error if myNullableInt is null
int c = (int)myNullableInt;
int d = myNullableInt.Value;    

// instead you need to do something like these, cumbersome and less readable
int e = myNullableInt ?? defaultValue;
int f = myNullableInt.HasValue ? myNullableInt : GetValueFromSomewhere();

我认为语言设计人员认为“引用类型默认情况下可为空”是一个错误,并且非空值是唯一明智的默认值,因此您应该选择使用空值。 (这在许多现代功能语言中都是这样。)“空”通常是一堆麻烦。

您似乎有2个不同的问题...

为什么我要在C#中使用不可为空的数据类型?

很简单,因为编译器保证您所依赖的值类型数据实际上具有值!

为什么我默认不选择可为空的类型,而仅在明确有意义的情况下才使用非可为空的类型?

正如Joel已经提到的那样,如果类型是引用类型,则只能为null。 编译器保证值类型具有值。 如果您的程序依赖于变量具有值,则这是您不选择可为空的类型所希望的行为。

当然,当您的数据来自不是程序的任何地方时,所有的赌注都关闭了。 最好的例子是来自数据库。 数据库字段可以为null ,因此您希望您的程序变量模仿该值-不仅仅是创建“代表” null的“魔术”值(即-1、0或其他null 您可以使用可为空的类型。

尽管null值可以方便地用作“ not-initialized-yet”或“ not-specified”值,但它们会使代码更加复杂,这主要是因为您正在重载null的含义以及变量(数字或-null与。

NULL值受到许多数据库设计人员和SQL数据库程序员的青睐,但是在思考问题上所做的更改很小,您可以消除null值,而实际上拥有更简单,更可靠的代码(例如,不必担心NullReferenceException )。

实际上,对“ T”的需求很大。 使得任何引用类型都不能为空的运算符,类似于“ T?” 使值类型可为空,C#的发明者Anders Hejlsberg希望他包括该功能。

另请参阅问题, 为什么C#和Java中存在“空”?

我倾向于在任何有意义的地方使用Nullable类型-在出现问题之前我不会在意性能,然后我将修复其中的少数问题并加以解决。

但是,我还发现,总的来说,我的大多数价值观最终都是不可为空的。 实际上,实际上我有很多次想要一个NotNullable,我可以将其与引用类型一起使用,以便在我得到null时发现有关null的问题,而不是稍后再尝试使用它时。

只有在数据库表中的某个字段绝对要求应用程序在某个时候发送或接收null的情况下,才应使用Nullable Type。 即使在这种情况下,也应该始终设法找到一种使用Nullable Type的方法。 布尔并不总是您最好的朋友。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM