当前位置:  开发笔记 > 编程语言 > 正文

首选:Nullable <>.HasValue或Nullable <>!= null?

如何解决《首选:Nullable<>.HasValue或Nullable<>!=null?》经验,为你挑选了4个好方法。

我总是使用(a)Nullable<>.HasValue因为我喜欢语义.然而,最近我正在研究其他人现有的代码库,他们Nullable<> != null专门使用(b)代替.是否有理由使用一个而不是另一个,还是纯粹的偏好?

(一个)

int? a;
if (a.HasValue)
    // ...

(b)中

int? b;
if (b != null)
    // ...

Rex M.. 440

编译器将null比较替换为调用HasValue,因此没有真正的区别.只要做一个对您和您的同事更具可读性/更有意义的事情.



1> Rex M..:

编译器将null比较替换为调用HasValue,因此没有真正的区别.只要做一个对您和您的同事更具可读性/更有意义的事情.


我会补充说"无论哪个更符合/遵循现有的编码风格."
在创建应用程序的早期阶段,您可能认为使用可空值类型来存储某些数据是足够的,只是在一段时间后才意识到您需要一个适合您目的的类.编写原始代码以与null进行比较后,您的优势在于您不需要使用null比较来搜索/替换对HasValue()的每次调用.
哇.我讨厌这种语法糖.`诠释?x = null`让我觉得可以为空的实例是一个引用类型.但事实是Nullable 是一种值类型.我觉得我会得到一个NullReferenceException:`int?x = null; 使用(x.HasValue)`.
抱怨能够将Nullable设置为null或将其与null进行比较是非常愚蠢的,因为它被称为Nullable**.问题是人们将"引用类型"与"可以为空"混为一谈,但这是一个概念上的混淆.Future C#将具有不可为空的引用类型.
@KFL如果语法糖困扰你,只需使用`Nullable `而不是`int?`.
@KFL我有时会使用`var z = x ?? y`为可空类型.你还喜欢`var z = x.HasValue吗?x:y`在那种情况下?看起来有点怪异.

2> cbp..:

我更喜欢(a != null)语法匹配引用类型.


它只会误导概念上的困惑.对两种不同类型使用一致的语法并不意味着它们是相同的类型.C#具有可为空的引用类型(所有引用类型当前都可以为空,但将来会发生变化)和可空值类型.对所有可空类型使用一致的语法是有意义的.它绝不意味着可空值类型是引用类型,或者可空引用类型是值类型.
当然,这是非常误导的,因为`Nullable <>`不是*参考类型.
是的,但事实上通常很重要,因为你是空检查.

3> Perrin Larso..:

我通过使用不同的方法将值赋给可空int来对此进行了一些研究.这是我做各种事情时发生的事情.应该澄清发生了什么.请记住:Nullable或者简写something?是一个结构,编译器似乎正在做很多工作,让我们使用null,就像它是一个类一样.
正如您将在下面看到的那样,SomeNullable == null并且SomeNullable.HasValue将始终返回预期的真或假.虽然下面没有说明,但SomeNullable == 3也是有效的(假设SomeNullable是一个int?).
虽然SomeNullable.Value得到了我们一个运行时错误,如果我们分配nullSomeNullable.事实上,这是唯一一个由于重载运算符,重载object.Equals(obj)方法,编译器优化和猴子业务的组合,nullables可能导致我们出现问题的情况.

以下是我运行的一些代码的说明,以及它在标签中生成的输出:

int? val = null;
lbl_Val.Text = val.ToString(); //Produced an empty string.
lbl_ValVal.Text = val.Value.ToString(); //Produced a runtime error. ("Nullable object must have a value.")
lbl_ValEqNull.Text = (val == null).ToString(); //Produced "True" (without the quotes)
lbl_ValNEqNull.Text = (val != null).ToString(); //Produced "False"
lbl_ValHasVal.Text = val.HasValue.ToString(); //Produced "False"
lbl_NValHasVal.Text = (!(val.HasValue)).ToString(); //Produced "True"
lbl_ValValEqNull.Text = (val.Value == null).ToString(); //Produced a runtime error. ("Nullable object must have a value.")
lbl_ValValNEqNull.Text = (val.Value != null).ToString(); //Produced a runtime error. ("Nullable object must have a value.")

好的,让我们尝试下一个初始化方法:

int? val = new int?();
lbl_Val.Text = val.ToString(); //Produced an empty string.
lbl_ValVal.Text = val.Value.ToString(); //Produced a runtime error. ("Nullable object must have a value.")
lbl_ValEqNull.Text = (val == null).ToString(); //Produced "True" (without the quotes)
lbl_ValNEqNull.Text = (val != null).ToString(); //Produced "False"
lbl_ValHasVal.Text = val.HasValue.ToString(); //Produced "False"
lbl_NValHasVal.Text = (!(val.HasValue)).ToString(); //Produced "True"
lbl_ValValEqNull.Text = (val.Value == null).ToString(); //Produced a runtime error. ("Nullable object must have a value.")
lbl_ValValNEqNull.Text = (val.Value != null).ToString(); //Produced a runtime error. ("Nullable object must have a value.")

和以前一样.请记住int? val = new int?(null);,使用null传递给构造函数初始化会产生COMPILE时间错误,因为可空对象的VALUE不可为空.只有包装器对象本身才能等于null.

同样,我们会得到一个编译时错误:

int? val = new int?();
val.Value = null;

更何况这val.Value是一个只读属性,这意味着我们甚至不能使用类似的东西:

val.Value = 3;

但同样,多态重载隐式转换运算符让我们做:

val = 3;

不管怎么说,只要它能正常工作,就不用担心多元化的问题了吗?:)


"请记住:Nullable 或简写的东西?是一个类." 这是错的!Nullable 是一个结构.与null相比,它重载Equals和==运算符以返回true.编译器没有花哨的工作来进行这种比较.
@andrewjs实际上,编译器在优化nullables方面做了大量工作.例如,如果为可归类型赋值,则它实际上根本不可为空(例如,`int?val = 42; val.GetType()== typeof(int)`).因此,不仅可以为一个可以等于null的结构,而且它通常也不是可以为空的!:D同样的方式,当你装入一个可以为空的值时,你是装箱`int`,而不是`int?` - 当`int?`没有值时,你得到`null`而不是盒装可空的价值.它基本上意味着很少有正确使用可空的任何开销:)

4> Carter Medli..:

在VB.Net中.当你可以使用".HasValue"时,不要使用"IsNot Nothing".我刚刚在一个地方用".HasValue"替换了"IsNot Nothing",解决了"操作可能使运行时不稳定"的中等信任错误.我真的不明白为什么,但在编译器中发生了不同的事情.我认为C#中的"!= null"可能会有同样的问题.


@steffan"IsNot Nothing"不是双重否定."没有"不是负面的,它是一个离散的数量,即使在编程领域之外."这个数量不算什么." 在语法上,与说"这个数量不是零"完全相同.并且都不是双重否定.
因为可读性,我更喜欢'HasValue`."IsNot Nothing"真的是一个丑陋的表达(因为双重否定).
这并不是说我不想在这里不同意真相,而是现在来吧.IsNot没有什么是明显的,过分消极的.为什么不写一些像HasValue一样积极和清晰的东西?这不是语法测试,而是编码,关键目标是清晰度.
jmbpiano:我同意这不是双重否定,但它是一个单一的否定,这几乎就像一个简单的积极表达一样丑陋而不清晰.
推荐阅读
乐韵答题
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有