服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C# - C#新特性之可空引用类型

C#新特性之可空引用类型

2023-02-09 15:34Sweet-Tang C#

本文详细讲解了C#新特性之可空引用类型,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

安装

您必须下载Visual Studio 2017 15.5预览版(目前最新发布版本是15.4),下载地址:https://www.visualstudio.com/en-us/news/releasenotes/vs2017-preview-relnotes。

安装Roslyn扩展预览版本:

  • 下载并解压 Roslyn_Nullable_References_Preview.zip [最新版本 11/15/17];
  • 关闭所有运行的Visual Studio;
  • 运行zip根目录中的 .\install.bat 脚本(如果需要卸载扩展,可以运行.\uninstall.bat脚本);

语法与类型

在语法上,可为空引用类型与可为空值类型使用的语法是一致的,在类型后面追加 ? 即可。

?
1
2
3
4
5
6
class Person
{
    public string FirstName;  
    public string? MiddleName;
    public string LastName;
}

我们都知道当初微软在增加可为空值类型的时候,实际是在框架中增加了System.Nullable<>类型,您肯定会问,可为空引用类型以框架中又增加了什么新的类型。

我们来看一个演示:

?
1
2
3
4
5
6
7
class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine(typeof(string?).FullName);
    }
}

输出结果:

C#新特性之可空引用类型

您是否觉得奇怪,怎么输出的是System.String,是的,其实微软在框架中没有加入任何类型,我们Person类型进行编译后,再通过dotPeek进行反编译,就明白到底发生了什么。

反编译后的结果:

?
1
2
3
4
5
6
7
internal class Person
{
    public string FirstName;
    [Nullable]
    public string MiddleName;
    public string LastName;
}

只是在MiddleName字段上增加了System.Runtime.CompilerServices.NullableAttribute标记。

我们来看一看属性、参数、变量、返回值编译之前与编译之后的比对结果。

属性

?
1
2
3
4
5
6
// 编译前:
public string? MiddleName { get; set; } 
 
// 编译后:
[Nullable]
public string MiddleName { [return: Nullable] get; [param: Nullable] set; }

参数

?
1
2
3
4
5
6
7
8
9
10
11
// 编译前:
public Person(string? middleName )
{
    this.MiddleName = middleName;
}
 
// 编译后:
public Person([Nullable] string middleName)
{
  this.MiddleName = middleName;
}

返回值

?
1
2
3
4
5
6
7
8
9
10
11
12
// 编译前:
public string? DoSomething()
{
    return null;
}
 
// 编译后:
[return: Nullable]
public string DoSomething()
{
  return (string) null;
}

变量

?
1
2
3
4
5
// 编译前:
string? name;
 
// 编译后:
string name;

这里除了变量,其它的都使用了NullableAttribute标记进行的修饰。

它可以做什么?

通过上面的章节,我们知道,可为空引用类型只是在参数、属性、参数和返回值中使用NullableAttribute标记进行修饰,实际上对程序的正常运行没有任何的影响。那么它可以为我们做什么呢?

表达意图

在C#中不能表达这个变量、参数、字段、属性,返回值等可能为null或不能为null,可为空类型可以帮我们解决这个问题。

?
1
2
3
4
5
6
class Person
{
    public string FirstName;   // 不为null
    public string? MiddleName; // 可能为null
    public string LastName;    // 不为null
}

这个类型的可以表示每一个人都应该 FristName 和 LastName ,但是不是每一个人都应该有 MiddleName。

编译器检测

可为空引用类型的另一个好处是编译器可以帮助我们检测代码,比如对于直接使用可为空引用类型的属性,编译器会发出警告

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void M(Person p)
{
    p.FirstName = null;          // 1 WARNING: Cannot convert null to non-nullable reference。
    p.LastName = p.MiddleName;   // 2 WARNING: Possible null reference assignment.
    string s = default(string);  // 3 WARNING: Cannot convert null to non-nullable reference。
    
    if (p.MiddleName != null)
    {
        WriteLine(p.MiddleName.Length); // ok
    }
    
     WriteLine(p.MiddleName!.Length); // ok
}
 
class Person
{
    public string FirstName;     // 4 WARNING: Non-nullable field 'FirstName' is uninitialized.
    public string? MiddleName;
    public string LastName;      // 5 WARNING: Non-nullable field 'LastName' is uninitialized.
}

编译器会帮我们做以下几点检测:

  • 如果给非可为空引用类型赋null值或可为空引用类型的值,则会发出警告;
  • 如果直接使用可为空引用类型,则会发出警告;
  • 如果从来没有给非可为空引用类型的属性赋值,则会发出警告;
  • 如果需要直接使用可为空引用类型,需要使用 ! 符号告诉编译器,您已经确认过该值不可能为空。

当然这只是编译器的行为,可以禁用与之相关的警告提示。

总结

空引用类型是一个语法糖,只是在编译器的层面帮我们发现可能发生的问题,对程序的正常运行没有任何作用。

到此这篇关于C#新特性之可空引用类型的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://www.cnblogs.com/tdfblog/p/Nullable-Reference-Types-Preview.html

延伸 · 阅读

精彩推荐
  • C#改进c# 代码的五个技巧(一)

    改进c# 代码的五个技巧(一)

    这篇文章主要介绍了改进c# 代码的五个技巧(一),帮助大家更好的理解和使用c#,感兴趣的朋友可以了解下...

    码农译站11472022-10-26
  • C#Unity AssetBundle打包工具示例详解

    Unity AssetBundle打包工具示例详解

    这篇文章主要介绍了Unity AssetBundle打包工具,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下...

    小紫苏xw7622022-12-06
  • C#Winform中如何跨线程访问UI元素

    Winform中如何跨线程访问UI元素

    这篇文章主要介绍了Winform中如何跨线程访问UI元素,帮助大家更好的理解和使用c#,感兴趣的朋友可以了解下...

    一只独行的猿8422022-10-13
  • C#C#中word导出功能的骚操作详解

    C#中word导出功能的骚操作详解

    这篇文章主要给大家介绍了关于C#中word导出功能骚操作的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,...

    随风去远方3892022-11-01
  • C#C#微信开发之启用开发者模式

    C#微信开发之启用开发者模式

    本文主要介绍了C#微信开发中启用开发者模式的步骤与方法,具有一定的参考价值,下面跟着小编一起来看下吧...

    likar9242021-12-22
  • C#用C#做网络爬虫的步骤教学

    用C#做网络爬虫的步骤教学

    在本篇内容里小编给大家分享的是关于用C#做网络爬虫的步骤和方法,需要的朋友们可以参考下。...

    C#教程网7912022-03-07
  • C#Unity实现俄罗斯方块(三)

    Unity实现俄罗斯方块(三)

    这篇文章主要为大家详细介绍了Unity实现俄罗斯方块的第一部分代码,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一...

    阿浪啊9562022-09-16
  • C#C# 基于消息发布订阅模型的示例(下)

    C# 基于消息发布订阅模型的示例(下)

    这篇文章主要介绍了C# 基于消息发布订阅模型的示例,帮助大家更好的理解和使用c#,感兴趣的朋友可以了解下...

    Hello——寻梦者!6792022-11-03