在数十年的编程中,NullReferenceException困扰着我们。尽管此异常很容易解决,但在其他地方发生此异常的可能性很高。
空引用异常的场景
首先让我们看一下发生空引用异常的情况。考虑下面这个名为Commit的类,其中包含数据、用户名、密码和提交消息,以及仅初始化名字和姓氏值的构造函数。
<font style="vertical-align: inherit;"><font style="vertical-align: inherit;">班级提交</font></font><font></font><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">{</font></font><font></font><font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> 公用字符串UserName {get; </font><font style="vertical-align: inherit;">组; </font><font style="vertical-align: inherit;">}</font></font><font></font><font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> 公共字符串密码{get; </font><font style="vertical-align: inherit;">组; </font><font style="vertical-align: inherit;">}</font></font><font></font><font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> 公共字符串CommitMessage {get; </font><font style="vertical-align: inherit;">组; </font><font style="vertical-align: inherit;">}</font></font><font></font><font></font><font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> 公共提交(字符串用户名,字符串密码)</font></font><font></font><font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> {</font></font><font></font><font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> UserName =用户名;</font></font><font></font><font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> 密码=密码;</font></font><font></font><font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> }</font></font><font></font><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">}</font></font><font></font>
如果使用构造函数创建Commit类的实例,并尝试获取CommitMessage的长度,则最终将导致null引用异常。
<font style="vertical-align: inherit;"><font style="vertical-align: inherit;">静态void Main(string [] args)</font></font><font></font><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">{</font></font><font></font><font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> 提交初始=新的Commit(“ Suresh”,“ $ trongPassword123”);</font></font><font></font><font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> int messageLength = GetMessageLength(initial);</font></font><font></font><font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> Console.WriteLine(messageLength);</font></font><font></font><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">}</font></font><font></font><font></font><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">static int GetMessageLength(公共人员)</font></font><font></font><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">{</font></font><font></font><font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> var commitMessage = person.CommitMessage;</font></font><font></font><font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> 返回commitMessage.Length;</font></font><font></font><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">}</font></font><font></font>
一旦发现这段代码将导致null引用异常,就可以通过给它一个null检查来修复它。
借助可为空的功能,即使在编译代码之前,也可以识别异常的发生。具体操作方法请往下看。
如何启用C#8.0
可为空的功能是C#8.0更新的一部分,您必须先确认您的项目已使用C#8.0编码,然后才能继续进行。
在最新版本的Visual Studio中,禁止在项目属性中更改语言版本的规定。

在进一步检查提供的链接时,我们发现,当项目的目标框架是.NET Core 3.x或.NET Standard 2.1时,默认语言版本是C#8.0。
<font style="vertical-align: inherit;"><font style="vertical-align: inherit;"><PropertyGroup></font></font><font></font><font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> <LangVersion>预览</ LangVersion></font></font><font></font><font style="vertical-align: inherit;"><font style="vertical-align: inherit;"></ PropertyGroup></font></font><font></font>
这将允许您使用编译器支持的预览c#语言中可用的特性。
使用可空的特性
<font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> <PropertyGroup></font></font><font></font><font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> <OutputType> Exe </ OutputType></font></font><font></font><font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> <TargetFramework> netcoreapp3.0 </ TargetFramework></font></font><font></font><font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> <Nullable>启用</ Nullable></font></font><font></font><font style="vertical-align: inherit;"><font style="vertical-align: inherit;"></ PropertyGroup></font></font><font></font>
这将导致Commit类的构造函数中出现警告,提示该CommitMessage未初始化。

避免警告和只担心错误是普通开发人员的天性。在这里,我们不能忽略这个警告,因为它会在运行时导致异常。因此,使用null值初始化CommitMessage。

仍然会显示警告。现在,通过将其声明为可为空的字符串(string,使CommitMessage属性接受null。
<font style="vertical-align: inherit;"><font style="vertical-align: inherit;">公共字符串lt;/font><font style="vertical-align: inherit;">CommitMessage {get; </font><font style="vertical-align: inherit;">组; </font><font style="vertical-align: inherit;">}</font></font>
尝试访问CommitMessage的长度时,警告将消失,并且新警告将显示在Program.cs类中。

如果CommitMessage为null ,则返回0处理该警告。现在,该程序不再有可能出现空引用异常。
<font style="vertical-align: inherit;"><font style="vertical-align: inherit;">static int GetMessageLength(公共人员)</font></font><font></font><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">{</font></font><font></font><font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> var commitMessage = person.CommitMessage;</font></font><font></font><font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> 如果(commitMessage为null)</font></font><font></font><font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> 返回0;</font></font><font></font><font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> 返回commitMessage.Length;</font></font><font></font><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">}</font></font><font></font>
您可以在点击此处下载该项目的副本。

标签:
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!