博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C#学习笔记(六):可空类型、匿名方法和迭代器
阅读量:5239 次
发布时间:2019-06-14

本文共 6504 字,大约阅读时间需要 21 分钟。

可空类型

为啥要引入可空类型?

在数据库中,字段是可以为null值的,那么在C#中为了方便的操作数据库的值,微软引入了可空类型。

声明可空类型

我们可以使用两种方法声明一个可空类型:

1 Nullable
i = null;2 int? i = null;

第二行是第一行的简写方法,其中“?”是微软为可空类型提供的一个语法糖。

我们看看可空类型的实现:

1 // Type: System.Nullable`1  2 // Assembly: mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089  3 // MVID: 255ABCDF-D9D6-4E3D-BAD4-F74D4CE3D7A8  4 // Assembly location: C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscorlib.dll  5   6 using System.Runtime;  7   8 namespace System  9 { 10   ///  11   /// 表示基础类型为值类型的对象,值类型与引用类型一样也可以分配 null。 12   ///  13   /// 
泛型类型的基础值类型。
1
14 [Serializable] 15 public struct Nullable
where T : struct 16 { 17 ///
18 /// 将
结构的新实例初始化为指定值。 19 ///
20 ///
一个值类型。 21 [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")] 22 public Nullable(T value); 23 ///
24 /// 创建一个新的
对象,并将其初始化为指定的值。 25 ///
26 /// 27 ///
28 /// 一个
对象,其
属性使用
参数进行初始化。 29 ///
30 ///
一个值类型。 31 public static implicit operator T?(T value); 32 ///
33 /// 返回指定的
的值。 34 ///
35 /// 36 ///
37 ///
参数的
属性的值。 38 ///
39 ///
一个
值。 40 public static explicit operator T(T? value); 41 ///
42 /// 检索当前
对象的值,或该对象的默认值。 43 ///
44 /// 45 ///
46 /// 如果
属性为 true,则为
属性的值;否则为当前
对象的默认值。 默认值的类型为当前
对象的类型参数,而默认值的值中只包含二进制零。 47 ///
48 [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")] 49 public T GetValueOrDefault(); 50 ///
51 /// 检索当前
对象的值或指定的默认值。 52 ///
53 /// 54 ///
55 /// 如果
属性为 true,则为
属性的值;否则为
参数。 56 ///
57 ///
如果
属性为 false,则为一个返回值。 58 public T GetValueOrDefault(T defaultValue); 59 ///
60 /// 指示当前
对象是否等于指定的对象。 61 ///
62 /// 63 ///
64 /// 如果
等于当前的
对象,则为 true;否则为 false。 此表描述如何定义所比较值的相等性: 返回值 说明 true
属性为 false,并且
参数为 null。 即,根据定义,两个 null 值相等。 - 或 -
属性为 true,并且
属性返回的值等于
参数。 false 当前
结构的
属性为 true,并且
参数为 null。 - 或 - 当前
结构的
属性为 false,并且
参数不为 null。 - 或 - 当前
结构的
属性为 true,并且
属性返回的值不等于
参数。 65 ///
66 ///
一个对象。
1
67 public override bool Equals(object other); 68 ///
69 /// 检索由
属性返回的对象的哈希代码。 70 ///
71 /// 72 ///
73 /// 如果
属性为 true,则为
属性返回的对象的哈希代码;如果
属性为 false,则为零。 74 ///
75 ///
1
76 public override int GetHashCode(); 77 ///
78 /// 返回当前
对象的值的文本表示形式。 79 ///
80 /// 81 ///
82 /// 如果
属性为 true,则是当前
对象的值的文本表示形式;如果
属性为 false,则是一个空字符串 ("")。 83 ///
84 ///
1
85 public override string ToString(); 86 ///
87 /// 获取一个值,指示当前的
对象是否有值。 88 ///
89 /// 90 ///
91 /// 如果当前的
对象具有值,则为 true;如果当前的
对象没有值,则为 false。 92 ///
93 public bool HasValue { [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] get; } 94 ///
95 /// 获取当前的
值。 96 ///
97 /// 98 ///
99 /// 如果
属性为 true,则为当前
对象的值。 如果
属性为 false,则将引发异常。100 ///
101 ///
属性为 false。
102 public T Value { [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")] get; }103 }104 }
View Code

我们注意一下其类的声明:

public struct Nullable
where T : struct

首先,可空类型是值类型而不是引用类型

where表明了其接受的类型仅仅是值类型,当然,引用类型天生就支持为null。

使用可空类型

我们来看一个使用可空的例子:

1 using System; 2  3 namespace Study 4 { 5     class Program 6     { 7         static void Main(string[] args) 8         { 9             int? i = null;10 11             // GetValueOrDefault() 如果为空则返回默认值12             Console.WriteLine("是否有值:" + i.HasValue + ", 值:" + i.GetValueOrDefault());13             14             //赋值15             if (!i.HasValue)16             {17                 i = 100;18             }19 20             Console.WriteLine("是否有值:" + i.HasValue + ", 值:" + i.Value);21 22             //int num = i * 2;23             //上面的写法会报错24             int num = i.Value * 2;25             Console.WriteLine("num:" + num);26 27             if (i == 100)28             {29                 Console.WriteLine("等于100");30             }31 32             Console.Read();33         }34     }35 }

输出如下:

1 是否有值:False, 值:02 是否有值:True, 值:1003 num:2004 等于100

空合并操作符

由于可空类型可以为空,所以,如果我们需要获取一个可空类型的值时,如果为null返回0,否则返回其自己的值,写法如下:

int i = nullable.HasValue ? nullable.Value : 0;

我们还可以直接使用GetValueOrDefault();方法来获取,如果是为null需要一个指定的数,如100的写法如下:

1 int i = nullable.HasValue ? nullable.Value : 100;2 int i = nullable.GetValueOrDefault(100);

上面两种写法的效果一致。

下面我们来看看空合并操作符“??”的效果:判断左方的数,如果不为空则返回左方的数,否则返回右方的数。

比如上面的效果用空合并操作符来写如下:

int i = nullable ?? 100;

我们可以把空操作符看做一种方便的简写形式。

匿名方法

闭包

一般一个方法内部定义的值对象会在方法或其作用域结束时被系统回收,但是如果使用匿名函数和Lambda表达式时会引入一种新的情况,导致方法内部定义的值对象不会再方法结束时被回收,这种想象称为闭包。

闭包的概念:主要是指由函数以及与函数相关的上下文环境组成的实体,通过闭包,函数与上下文变量之间建立起关联关系,上下文变量的状态可以在函数的多次调用过程中持久保持,从作用域的角度而言,私有变量的生存期被延长,函数调用所生成的值在下次调用时仍被保持。从安全性的角度而言,闭包有利于信息隐蔽,私有变量只在该函数内可见。

形成闭包的条件:嵌套定义的函数、匿名函数、将函数作为参数或者返回值。

我们来看一个闭包的例子:

1 using System; 2  3 namespace Study 4 { 5     class Program 6     { 7         static void Main(string[] args) 8         { 9             TCloser a = new TCloser();10             Func
b = a.T1();11 Console.WriteLine(b());12 13 Console.Read();14 }15 }16 17 public class TCloser18 {19 public Func
T1()20 {21 int n = 999;22 return () =>23 {24 Console.WriteLine(n);25 return n;26 };27 }28 }29 }

我们会发现,例子中T1的局部变量n,在T1执行完毕后仍然被保留没有被系统回收,而在其返回的方法中可以被使用到,这就是闭包。

迭代器 

转载于:https://www.cnblogs.com/hammerc/p/4608356.html

你可能感兴趣的文章
vs2010 项目生成成功,发布失败
查看>>
把文件保存到 sdcard
查看>>
大数据时代下的企业管理创新
查看>>
ES6数组
查看>>
洛谷 [P2051] 中国象棋
查看>>
『题解』UVa11324 The Largest Clique
查看>>
iPhone深入浅出 iOS 之生命周期
查看>>
算法笔记_097:蓝桥杯练习 算法提高 P1001(Java)
查看>>
OpenGL3-绘制各种图元绘制
查看>>
elasticsearch 聚合查询
查看>>
安卓app测试之Monkeyrunner
查看>>
C++小点之可调用类型声明std::function
查看>>
华为项目Tree canvas画图 数据4
查看>>
Python os.getcwd() 方法
查看>>
python os.path模块
查看>>
封装连接数据库
查看>>
[NSURL URLWithString:] returns nil
查看>>
多线程-内存模型
查看>>
多线程下载,以及断点的实现
查看>>
js中期轮播事件
查看>>