大佬教程收集整理的这篇文章主要介绍了I am a passionate coder ^_^,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
title="I am a passionate coder ^_^" alt="I am a passionate coder ^_^" src="https://cn.js-code.com/res/2019/02-07/10/845005d9744e21765915cc94639db3d6.jpg">
可空引用类型?
自从我开始学习.NET,引用类型一直就是可空的。然而初级程序员通常会告诉你值类型不可空,引用类型可空。
事实上,在.NET中有一种语法可以表明一个值类型是否可空。
int? nullableInt1 = null; NullablenullableInt2 = null; int nullableInt3 = null; //编译错误
并且这种语法并不只适用于原始类型,它也适用于struct
struct MyStruct {}
static void Main(String[] args)
{
MyStruct? mystruct1 = null;
MyStruct myStruct2 = null;
}
但是现在我们希望在编译以下代码时,编译器能给出错误或者警告
class MyClass {}
这里我们第一个问题就是,为什么需要让编译器给出错误或者警告?
我们接下来已一段简单的代码为例。
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();
}
这样的代码看起来很傻,但是现实情况中确实会发生,有人会将@H_934_15@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文件中添加一行:
true
就可以了。
一旦我们启用了该功能,让我们看一段简单的代码来说明它是如何工作的。
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.
所以这两个警告都不会阻止@R_639_9616@程序运行,但它会警告我们我们可能遇到麻烦。
下面让我们修改代码,让我们的引用类型变量可空
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; }@H_934_15@myClass.SayHello();}
如果你希望用错误替换警告,你可以升级整个检查到严格模式。这里你只需要在项目的csproj文件中添加一行:
true
以上是大佬教程为你收集整理的I am a passionate coder ^_^全部内容,希望文章能够帮你解决I am a passionate coder ^_^所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。