欢迎访问 生活随笔!

尊龙游戏旗舰厅官网

当前位置: 尊龙游戏旗舰厅官网 > 编程语言 > c# >内容正文

c#

c#学习笔记(六):可空类型、匿名方法和迭代器 -尊龙游戏旗舰厅官网

发布时间:2025/1/21 c# 22 豆豆
尊龙游戏旗舰厅官网 收集整理的这篇文章主要介绍了 c#学习笔记(六):可空类型、匿名方法和迭代器 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

为啥要引入可空类型?

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

声明可空类型

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

1 nullable<int> 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, 值:0 2 是否有值:true, 值:100 3 num:200 4 等于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表达式和事件的学习

闭包

一般一个方法内部定义的值对象会在方法或其作用域结束时被系统回收,但是如果使用匿名函数和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<int> b = a.t1(); 11 console.writeline(b()); 12 13 console.read(); 14 } 15 } 16 17 public class tcloser 18 { 19 public func<int> t1() 20 { 21 int n = 999; 22 return () => 23 { 24 console.writeline(n); 25 return n; 26 }; 27 } 28 } 29 }

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

ienumerable、ienumerator与yield的学习

yield学习续:yield return迭代块在unity3d中的应用——协程

总结

以上是尊龙游戏旗舰厅官网为你收集整理的c#学习笔记(六):可空类型、匿名方法和迭代器的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得尊龙游戏旗舰厅官网网站内容还不错,欢迎将尊龙游戏旗舰厅官网推荐给好友。

  • 上一篇:
  • 下一篇:
网站地图