原文:Nullable Reference Types In C# 8
作者:.NET Core Tutorials
译者:Lamond Lu


现状

可空引用类型

自从我开始学习.NET, 引用类型一直就是可空的。然而初级程序员通常会告诉你值类型不可空,引用类型可空。

事实上,在.NET中有一种语法可以表明一个值类型是否可空。

int? nullableInt1 = null;Nullable<int> nullableInt2 = null;int nullableInt3 = null; //编译错误

并且这种语法并不只适用于原始类型,它也适用于struct

Tips: Struct本身就是值类型

struct MyStruct{

}

static void Main(string[] args){    MyStruct? mystruct1 = null;    MyStruct myStruct2 = null;}

但是现在我们希望在编译以下代码时,编译器能给出错误或者警告

class MyClass{

}

static void Main(string[] args){    MyClass myClass = null; }

为什么?

这里我们第一个问题就是,为什么需要让编译器给出错误或者警告?

我们接下来已一段简单的代码为例。

class MyClass{    public void SayHello(){        Console.WriteLine("Hello");    }}

static void Main(string[] args){    var myClass = new MyClass();     myClass.SayHello();}

这个代码是某个功能的最初版本,看起来非常的简单,并且会运行的很好。

现在我们想象一下,一段之间之后,另外一个程序员加入了项目,将程序修改如下

class MyClass{    public void SayHello(){        Console.WriteLine("Hello");    }}

static void Main(string[] args){    var myClass = new MyClass();

    ...

    if (true)      {        myClass = null;    }

    ...

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

    ...

    myClass.SayHello();}

这样的代码看起来很傻,但是现实情况中确实会发生,有人会将myClass设置为null来满足他们正在处理的功能。它深藏在程序中,甚至可以通过单元测试,所有的功能看起来都运行良好。

但是在某个特定的时间点, 特定的条件下,程序会抛出一个NullReferenceException空引用异常, 这时候我们才会发现我们缺少了空引用判断,然后添加一定的防护。

class MyClass{    public void SayHello(){        Console.WriteLine("Hello");    }}

static void Main(string[] args){    var myClass = new MyClass();

    ...

    if (true)      {        myClass = null;    }

    ...

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

    ...

    if(myClass != null)    {         myClass.SayHello();       }}

那么如何避免其他程序员,或者未来的自己,陷入这种空引用的陷阱呢?

启用可空引用类型

如上所述,这里我们首先需要使用C#8的Nullable Reference Types功能。 完成后,只需要在项目的csproj文件中添加一行:

<NullableReferenceTypes>trueNullableReferenceTypes>

就可以了。

编译器产生警告

一旦我们启用了该功能,让我们看一段简单的代码来说明它是如何工作的。

class MyClass{    public void SayHello(){        Console.WriteLine("Hello");    }}

static void Main(string[] args){    MyClass myClass = null;    myClass.SayHello();}

如果编译以上代码的话,我们会得到2个警告。这里我使用了加粗字体,是因为我们得到的只是警告,不是编译错误。你的程序依然可以编译和启动。

第一个警告是我们尝试将null分配给未明确设置为允许空值的变量。

Converting null literal or possible null value to non-nullable type.

第二个警告是当我们尝试实际使用非可空类型时,编译器认为它将为null。

Possible dereference of a null reference.

所以这两个警告都不会阻止我们的应用程序运行,但它会警告我们我们可能遇到麻烦。

下面让我们修改代码,让我们的引用类型变量可空

C# 8中可用引用类型的定义于可空值类型一样,即在声明时,类型名的后面加?号

static void Main(string[] args){    MyClass? myClass = null;    myClass.SayHello();}

这里有趣的是,修改完代码后,编译项目,你依然会收到Possible dereference的警告。为了消除掉这个警告,你可以添加空引用检查。

static void Main(string[] args){    MyClass? myClass = null;    if (myClass != null)    {        myClass.SayHello();    }}

至此,所有的警告都消失了。

编译器警告的限制

在我们实际编码过程中,引用类型可以在方法,类,甚至程序集中传递。因此抛出警告时,它并不是万无一失的。例如,我们有如下代码:

class MyClass{    public Random Random = new Random();}

static void Main(string[] args){    MyClass myClass = new MyClass();    SomeMethod(myClass);    var next = myClass.Random.Next(1, 10);}

static void SomeMethod(MyClass myClass){    myClass.Random = null;}

这里编译器只会警告我们在分配一个null值给一个没有明确指定可空的变量。但是我们不会得到Possible dereference的警告。这里我们可以推断,一旦将对象传递到方法之外,无论在那里发生什么(如设置null),我们都不会被警告。但是如果我们在相同的代码/方法块中如此明确地分配null,然后尝试使用它,那么编译器将尝试给我们一个帮助。

为了与上述代码比较,以下代码确实会收到2条警告

static void Main(string[] args){    MyClass myClass = new MyClass();    if (new Random().Next(1, 10) > 5)    {        myClass = null;    }

    myClass.SayHello();}

启用可空引用类型的严格模式

如果你希望用错误替换警告,你可以升级整个检查到严格模式。这里你只需要在项目的csproj文件中添加一行:

<TreatWarningsAsErrors>trueTreatWarningsAsErrors>

注意: 这会将所有警告视为错误,而不仅仅是关于空引用问题的警告。但这意味着如果有警告被抛出,你的项目将不再编译!

c#加粗代码_C# 8中的可空引用类型相关推荐

  1. c#加粗代码_C# 按钮改变字体样式和加粗和斜体

    展开全部 用个Label为例子,当62616964757a686964616fe59b9ee7ad9431333337383836然你其他可以有文字显示的控件都可以Label label1=new L ...

  2. c#加粗代码_C# 按钮改变字体样式和加粗和斜体

    满意答案 sino0759 推荐于 2017.09.18 采纳率:42%    等级:8 已帮助:862人 有Font对象,桐厅其局谨隐有各种属性,完成后赋你要应用的对象. 以设置粗体为晌磨例 pri ...

  3. c#加粗代码_c#窗体,选中复选框,文字加粗变绿代码

    展开全部 private void Check1_CheckedChanged(object sender, EventArgs e) { CheckBox ck = sender as CheckB ...

  4. python中字体加粗_全网python中xticks字体加粗搜索-第二电脑网

    第二电脑网 网页 电脑论坛 电脑知识 搜吧 问问 博客 新闻 更多» soso.mark('logo_start'); soso.mark('logo_end'); 帮助 | 第二电脑网为主页 | 提 ...

  5. vb语言中怎样编码窗体中所有字体加粗_VBText控件中使字体加粗和倾斜的代码是什么...

    展开全部 VBText控件中使字体加粗和倾e69da5e6ba9062616964757a686964616f31333365656537斜的代码是: 加粗 Label1.FontBold = Tru ...

  6. html加粗代码样式,css如何设置字体加粗样式?

    css可以通过font-weight属性来设置字体加粗.font-weight属性可用于设置文本的粗细,一般设置该属性的值为bold或bolder来加粗字体. css可以通过font-weight属性 ...

  7. c#写字板实现加粗功能_Windows 7中写字板和绘画中的新功能

    c#写字板实现加粗功能 WordPad and Paint are often overlooked accessories included in all versions of Windows s ...

  8. pythontkinter字体加粗代码_Tkinter Fonts(字体)(示例代码)

    简单的tuple字体: 作为一个tuple的第一个元素是字体家族,一个点的大小,可选择一个字符串,包含一个或更多的粗体,斜体,下划线的样式修饰符,加粗. 例子: ("Helvetica&qu ...

  9. html语言怎么把文本加粗,如何在HTML中制作粗体文字?

    在前端页面的开发中,字体文字的效果是一个重要的部分,有时为了突出一段文字,就需要给文字进行加粗显示:那么在HTML中如何加粗文字,制作粗体文字?下面本篇文章就来给大家介绍一下,希望对大家有所帮助. i ...

  10. wps表格粗线和细线区别_WPS文字如何加粗或改变表格中某一条线的颜色? 经验告诉你该这样...

    为了在汇报工作中显示出与众不同,需要一副漂亮的文字排版,也有一些汇报文件对表格有相应的要求如下图所示,而不少人在制作表格时不知道如何将表名和表内容通过加粗或颜色区分开来,希望本文的能为大家提供一些帮助 ...

最新文章

  1. WPS菜单栏自动隐藏的解决方法
  2. loadrunner监控linux性能指标,使用LoadRunner监控Linux系统性能.doc
  3. day32 java的多线程(4)synchronized
  4. vs2005部署报表服务器项目老提示输入用户名密码解决办法
  5. C++友元:友元函数、友元类和友元成员函数
  6. 现在很多公司都在辞退年龄超过35岁以上的员工,原因到底为什么?
  7. Python+OpenCV:直方图均衡化(Histogram Equalization)
  8. FileZilla:425 Can't open data connection for transfer of解决办法
  9. android+接入易宝支付,iOS客户端连接易宝支付接口
  10. 360se html怎么删除,删除360浏览器的方法 如何删除360浏览器?
  11. 背景的css代码,CSS 背景(示例代码)
  12. 第十章(项目沟通管理)知识点
  13. 小米笔记本 镜像_小米笔记本Air 13.3 指纹版安装黑苹果 macOS High Sierra 10.13 教程...
  14. 第九章 亚瑟龙的召唤
  15. 第1讲、Cadence Allergo绘制小马哥DragonFly四轴飞行器PCB四层板教程简介
  16. 360极速浏览器审查模式保存图片
  17. c语言编程三角波,STM32 三角波输出
  18. 一秒等于多少毫秒_[UUG系列]1.1 泊松分布告诉你去奶茶店排队会遇到多少个小姐姐...
  19. LittleAlterBoy.dll VST插件
  20. 2023年12306购票平台自动化购票一|解决登录问题

热门文章

  1. 普通函数和Generator函数递归获取嵌套数组的最大值
  2. css中如何将a标签设置居中,cssa标签设置成block后,怎么让文字垂直居中_html/css_WEB-ITnose...
  3. tc自动服务器,使用linux下的TC进行服务器流量控制
  4. 分段路由_如何理解段路由(SPRING)?—Vecloud微云
  5. npm ERR! Cannot read property ‘resolve‘ of undefined
  6. 王传福:电动汽车开始由政策与市场双轮驱动|电动车百人会2019
  7. iOS开发之 WebView
  8. 【ANDROID游戏开发二十六】追加简述SURFACEVIEW 与 GLSURFACEVIEW效率!
  9. SPOJ Problem 1419:A Game with Numbers
  10. 通过HttpURLConnection模拟post表单提交