ImageVerifierCode 换一换
格式:DOCX , 页数:16 ,大小:169.51KB ,
资源ID:3753236      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/3753236.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(C#中的using和yield return混合使用.docx)为本站会员(b****3)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

C#中的using和yield return混合使用.docx

1、C#中的using和yield return混合使用 最近写代码为了为了省事儿用了几个yield return,因为我不想New一个List或者T对象再往里放元素,就直接返回IEnumerable了。我的代码里还有很多需要Dispose的对象,所以又用了几个using。写着写着我有点心虚了这样混合使用靠谱吗? 今天我花时间研究一下,并在这里作个笔记,跟大家分享。笔者水平有限,有哪些理解错误或做的不到位的地方,还请各位专家点拨。 这是我写的方法,循环外面一个using,整个方法里代码执行后释放一个对象。循环里面又一个using, 每次循环yield return后要释放一个对象。那是不是任何情况

2、下这些被创建了的需要释放的DisposableObject对象最后都会被释放呢? private static IEnumerable GetNumbers(int count) using (DisposableObject parentDisposableObject = new DisposableObject(ParentDisposableObject) foreach (int number in Enumerable.Range(1, count) using (DisposableObject childDisposableObject = new DisposableObje

3、ct(string.Format(ChildDisposableObject0, number) /if (number = 4) / / throw new Exception(异常。); / if (number != 2) yield return number * 10; else Console.WriteLine( 循环0 else 代码执行了, number.ToString(); Console.WriteLine( 循环0else下面的代码执行了, number.ToString(); 需要释放资源的类定义如下,创建对象和释放时都有输出。class DisposableObj

4、ect : IDisposable private string _value; public DisposableObject(string value) _value = value; Console.WriteLine(Create Object 0, _value); public void Dispose() Console.WriteLine(Disposable Object 0, _value); 这里调用下: static void Main(string args) foreach (int number in GetNumbers(5) Console.WriteLine

5、(结果 0, number.ToString(); 看看运行结果: 我们可以看到:1、循环外面的对象和循环里面的DisposableObject对象都被释放了,这个让我很高兴,要的就是这个效果;2,如果yield return后面还有代码,yield return后还会继续执行;3,if-else有作用,不满足条件可以不把该项作为结果返回,不想执行某段代码可以放里。这个运行的结果我很满意,就是我想要的! 下面我把抛异常的代码注释去掉,看看循环内抛出的异常后能否正常释放对象。结果很完美,担忧是多余的,该释放的DisposableObject对象都被释放了! 那么我们简单研究下yield retu

6、rn吧,我写了下面最简单的代码: private static IEnumerable GetNumbers(int numbers) foreach (int number in numbers) yield return number*10; 把项目编译再反编译成C#2.0,发现代码变成了这个样子:private static IEnumerable GetNumbers(int numbers) d_0 d_ = new d_0(-2); d_.3_numbers = numbers; return d_; 这里的d_0是个自动生成的类(看来这是高热量的语法糖,吃的是少了,程序集却发胖了

7、!),它实现了IEnumerable,IEnumerator等接口,而上面方法其实就是返回了一个封装了迭代器块代码的计数对象而已,如果您仅仅调用了一下上面这个方法,它可能不会执行循环中的代码,除非触发了返回值的MoveNext方法,这就是传说中的延迟求值吧!CompilerGeneratedprivate sealed class d_0 : IEnumerable, IEnumerable, IEnumerator, IEnumerator, IDisposable / Fields private int 1_state; private int 2_current; public int

8、 3_numbers; public int 7_wrap3; public int 7_wrap4; private int l_initialThreadId; public int 5_1; public int numbers; / Methods DebuggerHidden public d_0(int 1_state); private void m_Finally2(); private bool MoveNext(); DebuggerHidden IEnumerator IEnumerable.GetEnumerator(); DebuggerHidden IEnumera

9、tor IEnumerable.GetEnumerator(); DebuggerHidden void IEnumerator.Reset(); void IDisposable.Dispose(); / Properties int IEnumerator.Current DebuggerHidden get; object IEnumerator.Current DebuggerHidden get; Expand Methods View Code 通过MSIL查看上面的foreach循环会调用MoveNext方法。entrypoint .maxstack 2 .locals init

10、 ( 0 int32 number, 1 class mscorlibSystem.Collections.Generic.IEnumerator1 CS$5$0000) L_0000: ldc.i4.5 L_0001: call class mscorlibSystem.Collections.Generic.IEnumerable1 ConsoleApplication1.Program:GetNumbers(int32) L_0006: callvirt instance class mscorlibSystem.Collections.Generic.IEnumerator1 msco

11、rlibSystem.Collections.Generic.IEnumerable1:GetEnumerator() L_000b: stloc.1 L_000c: br.s L_0026 L_000e: ldloc.1 L_000f: callvirt instance !0 mscorlibSystem.Collections.Generic.IEnumerator1:get_Current() L_0014: stloc.0 L_0015: ldstr u7ed3u679cuff1a0 L_001a: ldloca.s number L_001c: call instance stri

12、ng mscorlibSystem.Int32:ToString() L_0021: call void mscorlibSystem.Console:WriteLine(string, object) L_0026: ldloc.1 L_0027: callvirt instance bool mscorlibSystem.Collections.IEnumerator:MoveNext() L_002c: brtrue.s L_000e L_002e: leave.s L_003a L_0030: ldloc.1 L_0031: brfalse.s L_0039 L_0033: ldloc

13、.1 L_0034: callvirt instance void mscorlibSystem.IDisposable:Dispose() L_0039: endfinally L_003a: ret .try L_000c to L_0030 finally handler L_0030 to L_003aView Code 而循环里面的执行内容都在MoveNext方法里。private bool MoveNext() try switch (this.1_state) case 0: this.1_state = -1; this.5_1 = new DisposableObject(P

14、arentDisposableObject); this.1_state = 1; this.7_wrap5 = Enumerable.Range(1, this.count).GetEnumerator(); this.1_state = 2; while (this.7_wrap5.MoveNext() this.5_2 = this.7_wrap5.Current; this.5_3 = new DisposableObject(string.Format(ChildDisposableObject0, this.5_2); this.1_state = 3; if (this.5_2

15、= 4) throw new Exception(异常。); if (this.5_2 = 2) goto Label_00D0; this.2_current = this.5_2 * 10; this.1_state = 4; return true; Label_00C7: this.1_state = 3; goto Label_00E8; Label_00D0: Console.WriteLine(循环0:else 内代码执行了 , this.5_2.ToString(); Label_00E8: Console.WriteLine(循环0:else下面的代码执行了 , this.5

16、_2.ToString(); this.m_Finally7(); this.m_Finally6(); this.m_Finally4(); break; case 4: goto Label_00C7; return false; fault this.System.IDisposable.Dispose(); View Code 接着再看下using,也来个最简单的。 using (DisposableObject parentDisposableObject = new DisposableObject(MainDisposableObject) Console.WriteLine(执

17、行.); /throw new Exception(异常。); 然后我们看一下对应的MSIL: .entrypoint .maxstack 1 .locals init ( 0 class ConsoleApplication1.DisposableObject parentDisposableObject) L_0000: ldstr MainDisposableObject L_0005: newobj instance void ConsoleApplication1.DisposableObject:.ctor(string) L_000a: stloc.0 L_000b: ldstr

18、 u6267u884c. L_0010: call void mscorlibSystem.Console:WriteLine(string) L_0015: leave.s L_0021 L_0017: ldloc.0 L_0018: brfalse.s L_0020 L_001a: ldloc.0 L_001b: callvirt instance void mscorlibSystem.IDisposable:Dispose() L_0020: endfinally L_0021: ret .try L_000b to L_0017 finally handler L_0017 to L

19、_0021 再换一种C#写法试试: DisposableObject parentDisposableObject = new DisposableObject(MainDisposableObject); try Console.WriteLine(执行.); /throw new Exception(异常。); finally parentDisposableObject.Dispose(); 对应的MSIL代码: .entrypoint .maxstack 1 .locals init ( 0 class ConsoleApplication1.DisposableObject pare

20、ntDisposableObject) L_0000: ldstr MainDisposableObject L_0005: newobj instance void ConsoleApplication1.DisposableObject:.ctor(string) L_000a: stloc.0 L_000b: ldstr u6267u884c. L_0010: call void mscorlibSystem.Console:WriteLine(string) L_0015: leave.s L_001e L_0017: ldloc.0 L_0018: callvirt instance

21、 void ConsoleApplication1.DisposableObject:Dispose() L_001d: endfinally L_001e: ret .try L_000b to L_0017 finally handler L_0017 to L_001e 看看两段MSIL多像啊,特别是最后一句! 最后我们看看yield return 和 using混合使用时,自动生成的d_0类是如何保证需要释放资源的DisposableObject对象被释放的,看后我不禁感慨:C#的编译器真是鬼斧神工啊! 1 private bool MoveNext() 2 3 try 4 5 swi

22、tch (this.1_state) 6 7 case 0: 8 this.1_state = -1; 9 this.5_1 = new DisposableObject(ParentDisposableObject);10 this.1_state = 1;11 this.7_wrap5 = Enumerable.Range(1, this.count).GetEnumerator();12 this.1_state = 2;13 while (this.7_wrap5.MoveNext()14 15 this.5_2 = this.7_wrap5.Current;16 this.5_3 =

23、 new DisposableObject(string.Format(ChildDisposableObject0, this.5_2);17 this.1_state = 3;18 if (this.5_2 = 4)19 20 throw new Exception(异常。);21 22 if (this.5_2 = 2)23 24 goto Label_00D0;25 26 this.2_current = this.5_2 * 10;27 this.1_state = 4;28 return true;29 Label_00C7:30 this.1_state = 3;31 goto

24、Label_00E8;32 Label_00D0:33 Console.WriteLine(循环0:else 内代码执行了 , this.5_2.ToString();34 Label_00E8:35 Console.WriteLine(循环0:else下面的代码执行了 , this.5_2.ToString();36 this.m_Finally7();37 38 this.m_Finally6();39 this.m_Finally4();40 break;41 42 case 4:43 goto Label_00C7;44 45 return false;46 47 fault48 49

25、 this.System.IDisposable.Dispose();50 51 52 53 54 55 1 public DisposableObject 5_1; 2 3 4 public DisposableObject 5_3; 5 6 7 private void m_Finally4() 8 9 this.1_state = -1;10 if (this.5_1 != null)11 12 this.5_1.Dispose();13 14 15 16 private void m_Finally7()17 18 this.1_state = 2;19 if (this.5_3 !=

26、 null)20 21 this.5_3.Dispose();22 23 24 25 void IDisposable.Dispose()26 27 switch (this.1_state)28 29 case 1:30 case 2:31 case 3:32 case 4:33 try34 35 switch (this.1_state)36 37 case 2:38 case 3:39 case 4:40 try41 42 switch (this.1_state)43 44 case 3:45 case 4:46 try47 48 49 finally50 51 this.m_Finally7();52 53 break;54 55 56 finally57 58 this.m_Finally6();59 60 break;61 62 63 finally64 65 this.m_Finally4();66 67 break;68 69 default:70 return;71 72

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1