检查是否为null:null与default()之间的比较?

33

我想要检查一个引用类型是否为null。我看到有两个选项(_settings是引用类型FooType):

if (_settings == default(FooType)) { ... }

if (_settings == null) { ... }

这两者有何不同表现?


使用 default(T),更易读。 - baltermia
7个回答

42

1
我不太同意:第一个比较是类型安全的(或者至少应该是),这就是在C#中null的基本问题,null == null是true,但左侧的null可能是一个字符串,而右侧的null可能是一个复杂对象,所以default(string)不应该等于default(complex object),如果每个人都停止使用null,那将是很好的。https://blog.miguelbernard.com/why-null-in-csharp-is-so-bad - Null
1
@Null:你假设null值有一种类型。这是真的吗? - Stephen Cleary
null包含所有类型,因此没有任何类型。你有阅读我所提到的博客吗? - Null
1
@Null:是的,我看过了,但我不同意赋值意味着继承的观点。我确实同意结论(尽管我不同意论点):启用可空类型检查是理想的。 - Stephen Cleary
在这一点上,我也同意。很抱歉我无法提出更好的论据。 - Null

19

现在我们不再需要将类型传递到默认值,因此优先使用default。

  • 它与以前一样易读

  • 它可用于值类型和引用类型

  • 它可用于泛型

    if (_settings == default) { ... }

此外,在调用之后

obj = enumerable.FirstOrDefault();

在这之后测试默认值更有意义,而不是测试 null 值。否则它应该被称为 FirstOrNull,但是 value 没有 null 值,但有默认值。


14

两者没有区别,但第二个更易读。在处理泛型时,使用default的最佳场所是通用代码return default(T);


2
对于 DateTime,它返回的是 "0001-01-01T00:00:00",这是一个有效值...不像 null 是无效值。 - Yousha Aleayoub
4
这句话的意思是“问题涉及引用类型,而DateTime不属于引用类型。” - Andrey
我认为这是一个主观看法问题。我在很多地方使用default(不带括号),因为我能直觉地知道我所使用的类型的默认值是什么。它可以表示null、DateTime.Min或者是int类型的0。对于那些不会自动将默认值注册在脑中的人来说,这样做会更具可读性。例如,它还可以帮助你搜索所有被赋予默认值的值。而不是搜索null0或者Decimal.Zero,你只需要搜索default== default,甚至是is default - Saturn K
1
@SaturnK 这是一个品味问题,我更喜欢显式值而不是默认关键字(Python的禅:显式优于隐式)。默认关键字是为了与模板类型一起使用而引入的,因为在默认情况下无法在那里使用显式值。 - Andrey

5

不是不同,但我认为

if (_settings == null) { ... }

更为清晰。

3

我的理解是它们并没有区别。只有在处理值类型时才会有所不同。


3

我肯定会选择对null值进行特定的检查。因为如果_settings类的类型发生更改,您可能会遇到引用问题。至少需要更改代码以打破开放/关闭策略。

if( _settings == null ) {...}

这样做更安全、更清洁。

2

如先前所述,default(<type>)null 没有区别,但是您仍然可能想要使用 default(<type>) 来处理非引用类型的情况。通常这只在泛型中出现,但养成这种习惯对于一般情况来说也是有好处的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接