c# 闭包

C# 中的闭包 在 C# 中,闭包是一个强大的概念,它允许函数捕获外部变量并在函数外部访问这些变量。闭包在很多场景下都非常有用,比如在匿名函数、Lambda 表达式和委托中。本教程将详细介绍 C# 中的闭包。return 10;匿名函数是一种没有名称的函数,它可以在代码中直接定义并使用。在 C# 中,匿名函数通常使用delegate关键字或 Lambda 表达式来定义。例如:在这个例子中,我们定义了一个匿名函数,并将其赋值给一个委托变量。这个匿名函数没有参数,并且返回值为 10。 阅读详情

 引用 http://www.cnblogs.com/zhouandke/p/5870257.html


1. 首先要说明的是, delegate 被编译器 编译成一个class, 所以才能传来传去(具体参考 《CLR via C#》第四版), 所以 Action、Func也是如此

2. 在C#中,原来闭包只是编译器玩的花招而已,它仍然没有脱离.NET对象生命周期的规则,它将需要修改作用域的变量直接封装到返回的类中变成类的一个属性,从而保证了变量的生命周期不会随函数调用结束而结束,因为变量n在这里已经成了返回的类的一个属性. 这个观点引用自C#与闭包, 写的很好, 将原文也贴出来吧

 

 

首先想说明一点,虽然有这样那样的不好的心态(比如中文技术书),但总体来说,国内的技术人员还是喜欢分享和教导别人的,这点我的个人感受和之前在园子里看到的朋友的感受恰恰相反.个人认为其实国内很多技术网友都是很热心的,可能因为语言问题同一个技术热点会稍稍落后国外一些,但一些成熟的或者基础的概念都可以找到很细致的中文介绍,特别是关于闭包,因为它的字面解释确实很绕,所以基本所有试图解释这一名词的同学都是尽量用自己认为最通俗易懂的方式来进行讲解.闲话扯远了,这里我就用C#语言来给大家解释下闭包吧.
其实要提到闭包,我们还得先提下变量作用域和变量的生命周期. 在C#里面,变量作用域有三种,一种是属于类的,我们常称之为field,第二种则属于函数的,我们通常称之为局部变量,还有一种,其实也是属于函数的,不过它的作用范围更小,它只属于函数局部的代码片段,这种同样称之为局部变量.这三种变量的生命周期基本都可以用一句话来说明,每个变量都属于它所寄存的对象,即变量随着其寄存对象生而生和消亡.对应三种作用域我们可以这样说,类里面的变量是随着类的实例化而生,同时伴随着类对象的资源回收而消亡(当然这里不包括非实例化的static和const对象).而函数(或代码片段)的变量也随着函数(或代码片段)调用开始而生,伴随函数(或代码片段)调用结束而自动由GC释放,它内部变量生命周期满足先进后出的特性。
那么这里有没有例外呢? 答案是有的,不过在提这点之前,我还需要给各位另外一个名词.都说c#就是MS版本的java,这话在.net 1.0可能可以这么说,但自2.0之后C#就可以自豪的说它绝非java了,这里面委托有很大的功劳,如果用过java和C#的人并且尝试过写winform程序时全部手写实现代码的人就会有这样一个感受,同样的click事件,在java中必须要无端的套个匿名类,但在c#中,你是可以直接将函数名+=到事件之后而不需要显示写上匿名委托的对象类型的,因为编译器会帮你做这部分工作,在3.0和以后的版本之中,微软将委托的用法更是发挥的淋漓精致,无论是简洁的Lamda还是通俗易懂的LINQ,都是源自委托的.
你可能要问,委托和我们今天要讲的闭包又有什么关系呢? 我们知道,c#,java和javascript,ruby,python这些语言不同,在c#和java的世界里面,原子对象就是类(当然还有struct和基本变量),而不是很多动态语言中的函数,我们可以实例化一个类,实例化一个变量,但不可以直接new 一个函数.也就是表面上看,我们是没办法像js那样将函数进行实例化和传递的.这也是为什么直到Java 7闭包才被姗姗来迟的加入java特性中。但对C#来说这些只是表象,我刚学c#的时候,看到最多的解释委托的话就是:委托啊,就相当于c++里面的函数指针啦.这句话虽然笼统,但确实有一定道理,通过委托特别是匿名委托这层对象的包装,我们就可以突破无法将函数当做对象传递的限制了.
好像这里还是没讲到闭包和委托的关系,好吧,我太啰嗦了,下面从概念开始讲. 闭包其实就是使用的变量已经脱离其作用域,却由于和作用域存在上下文关系,从而可以在当前环境中继续使用其上文环境中所定义的一种函数对象. 好拗口,程序员,还是用示例来说明更好理解. 首先来个最简单的javascript中常常见到的关于闭包的例子:

这段代码翻译成C#代码就是这样:    

?
public class TCloser
     {
         public Func< int > T1()
         {
             var n = 999;
             return () =>
             {
                 Console.WriteLine(n);
                 return n;
             };
         }
     }
    
     class Program{
         static void Main(){
             var a = new TCloser();
             var b = a.T1();
             Console.WriteLine(b());
         }
     }

    从上面的代码我们不难看到,变量n实际上是属于函数T1的局部变量,它本来生命周期应该是伴随着函数T1的调用结束而被释放掉的,但这里我们却在返回的委托b中仍然能调用它,这里正是闭包所展示出来的威力,因为T1调用返回的匿名委托的代码片段中我们用到了n,而在编译器看来,这些都是合法的,因为返回的委托b和函数T1存在上下文关系,也就是说匿名委托b是允许使用它所在的函数或者类里面的局部变量的,于是编译器通过一系列动作(具体动作我们后面再说)使b中调用的函数T1的局部变量自动闭合,从而使该局部变量满足新的作用范围。     因此如果你看到.net中的闭包,你就可以像js中那样理解它,由于返回的匿名函数对象是在函数T1中生成的,因此相当于它是属于T1的一个属性。如果你把T1的对象级别往上提升一个层次就很好理解了,这里就相当于T1是一个类,而返回的匿名对象则是T1的一个属性,对属性而言,它可以调用它所寄存的对象T1的任何其他属性或者方法,包括T1寄存的对象TCloser内部的其他属性。如果这个匿名函数会被返回给其他对象调用,那么编译器会自动将匿名函数所用到的方法T1中的局部变量的生命周转期自动提升并与匿名函数的生命周期相同,这样就称之为闭合。         也许你会说,这个返回的委托包含的变量n只是编译器通过某种方式隐藏的对这个委托对象的一个同样对象的赋值吧,那么我们再对比下面两个方法:    

?
public class TCloser{
public Func< int > T1()
     {
         var n = 999;
         Func< int > result = () =>
         {
             return n;
         };
 
         n = 10;
         return result;
     }
 
     public dynamic T2()
     {
         var n = 999;
         dynamic result = new { A = n };
         n = 10;
         return result;
     }
     static void Main(){
         var a = new TCloser();
         var b = a.T1();
         var c = a.T2();
         Console.WriteLine(b());
         Console.WriteLine(c.A);
     }
}

    最后输出结果是什么呢?答案是10和999,因为闭包的特性,这里匿名函数中所使用的变量就是实际T1中的变量,与之相反的是,匿名对象result里面的A只是初始化时被赋予了变量n的值,它并不是n,所以后面n改变之后A并未随之而改变。这正是闭包的魔力所在。         你可能会好奇.net本身并不支持函数对象,那么这样的特性又是从何而来呢?答案是编译器,我们一看IL代码便会明白了。     首先我给出c#代码:    

?
public class TCloser {
         public Func< int > T1(){
             var n = 10;
             return () =>
             {
                 return n;
             };
         }
 
         public Func< int > T4(){
             return () =>
             {
                 var n = 10;
                 return n;
             };
         }
     }

    这两个返回的匿名函数的唯一区别就是返回的委托中变量n的作用域不一样而已,T1中变量n是属于T1的,而在T4中,n则是属于匿名函数本身的。但我们看看IL代码就会发现这里面的大不同了:    

?
.method public hidebysig instance class [mscorlib]System.Func`1<int32> T1() cil managed{
     .maxstack 3
     .locals init (
         [0] class ConsoleApplication1.TCloser/<>c__DisplayClass1 CS$<>8__locals2,
         [1] class [mscorlib]System.Func`1<int32> CS$1$0000)
     L_0000: newobj instance void ConsoleApplication1.TCloser/<>c__DisplayClass1::.ctor()
     L_0005: stloc.0
     L_0006: nop
     L_0007: ldloc.0
     L_0008: ldc.i4.s 10
     L_000a: stfld int32 ConsoleApplication1.TCloser/<>c__DisplayClass1::n
     L_000f: ldloc.0
     L_0010: ldftn instance int32 ConsoleApplication1.TCloser/<>c__DisplayClass1::<T1>b__0()
     L_0016: newobj instance void [mscorlib]System.Func`1<int32>::.ctor( object , native int )
     L_001b: stloc.1
     L_001c: br.s L_001e
     L_001e: ldloc.1
     L_001f: ret
}
 
.method public hidebysig instance class [mscorlib]System.Func`1<int32> T4() cil managed
{
     .maxstack 3
     .locals init (
         [0] class [mscorlib]System.Func`1<int32> CS$1$0000)
     L_0000: nop
     L_0001: ldsfld class [mscorlib]System.Func`1<int32> ConsoleApplication1.TCloser::CS$<>9__CachedAnonymousMethodDelegate4
     L_0006: brtrue.s L_001b
     L_0008: ldnull
     L_0009: ldftn int32 ConsoleApplication1.TCloser::<T4>b__3()
     L_000f: newobj instance void [mscorlib]System.Func`1<int32>::.ctor( object , native int )
     L_0014: stsfld class [mscorlib]System.Func`1<int32> ConsoleApplication1.TCloser::CS$<>9__CachedAnonymousMethodDelegate4
     L_0019: br.s L_001b
     L_001b: ldsfld class [mscorlib]System.Func`1<int32> ConsoleApplication1.TCloser::CS$<>9__CachedAnonymousMethodDelegate4
     L_0020: stloc.0
     L_0021: br.s L_0023
     L_0023: ldloc.0
     L_0024: ret
}

看IL代码你就会很容易发现其中究竟了,在T1中,函数对返回的匿名委托构造的是一个类,名称为newobj instance void ConsoleApplication1.TCloser/<>c__DisplayClass1::.ctor(),而在T4中,则是仍然是一个普通的Func委托,只不过级别变为类级别了而已。 那我们接着看看T1中声明的类c__DisplayClass1是何方神圣:

?
. class auto ansi sealed nested private beforefieldinit <>c__DisplayClass1
     extends [mscorlib]System.Object{
     .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor()
     .method public hidebysig specialname rtspecialname instance void .ctor() cil managed{}
     .method public hidebysig instance int32 <T1>b__0() cil managed{}
     .field public int32 n
}

看到这里想必你已经明白了,在C#中,原来闭包只是编译器玩的花招而已,它仍然没有脱离.NET对象生命周期的规则,它将需要修改作用域的变量直接封装到返回的类中变成类的一个属性n,从而保证了变量的生命周期不会随函数T1调用结束而结束,因为变量n在这里已经成了返回的类的一个属性了。
看到这里我想大家应该大体上了解C#闭包的来龙去脉了吧,C#中,闭包其实和类中其他属性、方法是一样的,它们的原则都是下一层可以畅快的调用上一层定义的各种设定,但上一层则不具备访问下一层设定的能力。即类中方法里的变量可以自由访问类中的所有属性和方法,而闭包又可以访问它的上一层即方法中的各种设定。但类不可以访问方法的局部变量,同理,方法也不可以访问其内部定义的匿名函数所定义的局部变量。
这正是C#中的闭包,它通过超越java语言的委托打下了闭包的第一步基础,随后又通过各种语法糖和编译器来实现如今在.NET世界全面开花的Lamda和LINQ.也使得我们能够编写出更加简洁优雅的代码。


C#中使用闭包与意想不到的坑详解 主要给大家介绍了关于C#中使用闭包与意想不到的坑,文中通过示例代码介绍的非常详细,对大家学习或者使用C#具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧 立即下载

相关推荐

Polyworks脚本开发学习笔记(一)-脚本开发环境

详细的总结和记录了利用Polyworks进行脚本开发的一些方法和心得

qq_43662503的博客 6795

C#闭包陷阱

用例: class Program { static void Main(string[] args) { List<Person> li = new List<Person>() { new Person("kk...

祝你万事顺利的博客 853

直线型一阶倒立摆1---从理论到实践的桥梁

本文深入探讨了直线型一阶倒立摆在控制理论中的核心地位,从非线性控制、鲁棒性到实时反馈等关键问题。通过实际案例和硬件搭建指南,帮助读者理解从理论到实践的过渡,特别适合控制工程初学者和研究人员。文章还提供了算法选型建议和硬件避坑手册,是掌握倒立摆控制的实用指南。

weixin_29047545的博客 317

使用Reflector查看闭包

第一种:.Net 3.5 代码:using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace 闭包{ class Program { static void Main(string[] args) { ...

weixin_30664051的博客 271

智能体评测技术与实践:从评估维度到DeepEval实战指南

智能体评测技术与实践:从评估维度到DeepEval实战指南 本文系统探讨了AI智能体的评测体系与实践方法。首先从四个关键维度构建评估框架:基础能力(意图理解、知识完整性)、复杂任务(多轮对话、动态工作流)、可靠性(幻觉抑制、安全合规)以及工具效率(参数填充、多工具协同)。其次分析了主流评测工具,包括xBench的动态双轨评估、DeepEval的全链路监控等解决方案。最后详细介绍了DeepEval的实战应用,涵盖环境配置、测试用例构建、指标配置及CI/CD集成,展示了如何通过代码化评估实现智能体质量的持续提升

Linda的自动化测试之旅 3413

ArcGIS新手必看:5分钟搞定等高线转DEM栅格(附完整操作截图)

本文详细介绍了在ArcGIS中将等高线转换为DEM栅格的完整流程,包括CAD数据预处理、TIN转栅格和直接插值法两种核心方法,以及常见问题排查与优化技巧。通过实战案例和操作截图,帮助GIS新手快速掌握这一测绘数据处理的核心技能,提升地形分析和三维可视化效率。

dapp9builder的博客 285

.NET 某智能服装智造系统 内存泄漏分析

二:Windbg 分析 到底是哪一方面的泄漏 根据朋友描述,程序运行一段时间后,内存就炸了,应该没造成人员伤亡,不然也不会跟我wx聊天了,这里可以用 .time 看看当前的 process 跑了多久。 0:000> .time Debug session time: Thu Oct 21 14:54:39.000 2021 (UTC + 8:00) System Uptime: 6 days 4:37:27.851 Process Uptime: 0 days 0:40:14.000 Kernel

weixin_45032957的博客 355

Alibaba Java Coding Guidelines,以后我的Java代码规范,就靠它了

前言 对于Java代码规范,业界有统一的标准,不少公司对此都有一定的要求。但是即便如此,庞大的Java使用者由于经验很水平的限制,未必有规范编码的意识,而且即便经验丰富的老Java 程序员也无法做到时刻将规范牢记于心。所以对于代码规范扫描工具,一经问世就广受青睐,阿里巴巴出品的Alibaba Java Coding Guidelines(阿里巴巴Java代码规约扫描,以下简称为AJCG)插件便是其...

java梦工厂 857

新版C#编译器关于函数闭包的一处更改

感谢@DiryBoy的补充,他提到这个问题在MSDN上是有说明的: http://msdn.microsoft.com/en-us/library/vstudio/hh678682.aspx 在VisualBasic.NET中,如果你写下类似下面的代码: PublicSubTest() Fori=0To100 ...

weixin_30338497的博客 271

WorkBuddy Skill赋能HYSYS与Comsol:AI工作台下的仿真自动化实践

AI Agent正将工业软件自动化带向新高度。在工程仿真领域,流程模拟与多物理场分析常因重复性操作而效率低下,Aspen HYSYS的批量工况调整、Comsol的参数扫描与网格重构均属此类。WorkBuddy这类AI工作台通过Skill将软件二次开发能力封装为可插拔技能包,利用HYSYS的COM/OLE接口和Comsol的Java API,实现自然语言指令到自动化执行的转变。其技术价值在于降低自动化门槛、沉淀工程经验,并支持日志审计与异常重试。在实际应用中,无论化工流程的灵敏度分析,还是激光焊接、移动网格等

weixin_29055699的博客 295

GPT大模型在数学建模中的实战应用:从思路启发到代码生成

数学建模是将现实问题抽象为数学问题并求解的核心方法,其关键在于通过合理的假设与简化,构建可计算的数学模型。传统建模依赖MATLAB等工具进行推演试错,而大语言模型的出现革新了这一范式。GPT等模型通过理解自然语言、辅助逻辑推理与代码生成,能有效提升建模效率与质量,在问题解析、模型构建、算法实现等环节提供关键支持。本文聚焦GPT在数学建模中的具体应用,涵盖赛题解读、模型推导、代码生成与结果分析,并结合实战案例,探讨如何将其作为“副驾驶”融入建模全流程,实现人机协同的智能化建模。

weixin_29061465的博客 322

c#闭包问题--踩过的一个大坑

引言 &amp;amp;enps;&amp;amp;enps;&amp;amp;enps;&amp;amp;enps;之前在做c#游戏开发的过程中,遇到了一个大坑。当时为了实现动态加载图鉴,用到了button的循环委托,谁知道这样就踩了c#闭包问题的大坑!现在对这个问题进行总结,避免下次再踩入这样的巨坑。 闭包的概念 Q:先抛出第一个问题,什么是闭包?闭包会出现在怎样的场景中? A:...

菜鸟想飞 3908

Zlib1.2.11源码编译(Win10+VS2019)

下载 下载网址: zlib Home Site 得到文件: 解压缩到“D:\SourceCodes\zlib-1.2.11” 使用CMake配置、生成并打开项目 将CMakeLists.txt拖入CMake,配置(Configure): 生成(Generate) 打开项目(Open Project),CMake调用VS2019打开项目 生成debug版本 构建项目ALL_BUILD。成功生成debug版本 在“D:\Sourc...

Alexabc3000的专栏 1892

c#闭包问题

而在第二个正确的例子里,在每一次循环中,会创建一个新的临时变量u来保存当前循环的i,当委托或Lambda创建时,闭包这个新的临时变量u,且每个不同委托引用的u是互相独立的,其到委托执行时都是不会变化的,所以使用临时变量来保存匿名函数想要引用的外部函数变量可以解决闭包陷阱。“foreach”的遍历中定义的临时循环变量会被逻辑上限制在循环内,“foreach”的每次循环都会是循环变量的一个拷贝,这样闭包就看起来关闭了(没有了)。在c#中,内层的函数可以引用包含在它外层的函数的变量,即使外层函数的执行已经终止。

qq_41184334的博客 1569

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

【C#】闭包

关于C#闭包的分析

m0_62389241的博客 2099

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

C#与闭包

首先想说明一点,虽然有这样那样的不好的心态(比如中文技术书),但总体来说,国内的技术人员还是喜欢分享和教导别人的,这点我的个人感受和之前在园子里看到的朋友的感受恰恰相反。个人认为其实国内很多技术网友都是很热心的,可能因为语言问题同一个技术热点会稍稍落后国外一些,但一些成熟的或者基础的概念都可以找到很细致的中文介绍,特别是关于闭包。因为它的字面解释确实很绕,所以基本所有试图解释这一名词的同学都是尽量

liguo9860的专栏 814

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

C#_闭包

C#_闭包 一、闭包的含义 首先,闭包并不是针对某一特定语言的概念,而是一个通用的概念。 闭包是指有权访问另一个函数作用域中的变量的函数。注意,闭包这个词本身值得是一种函数。而创建这种特殊函数的一种常见方式是在一个函数中创建另一个函数。在C#中我们可以使用委托或者本地函数。 二、理解闭包的实现原理 static void Main(string[] args) { GetAction()(30); } static A

目标:MVP 4055

c#闭包原理

c#闭包是一个很强大的功能,在平时项目中会经常用到,我们大多数人在体验其便利性的同时,可能不会去考虑其背后的原理。这篇文章简要讲述闭包的工作原理,已帮助大家正确的使用闭包。闭包的概念应该源于离散数学这门计算机基础课程,离散数学中,一个关系R的闭包,是指加上最小数目的有序偶而形成的具有自反性,对称性或传递性的新的有序偶集,此集就是关系R的闭包。1通俗理解就是一在一个不完全的关系集上加上某些特定的序偶对使其满足了关系的某个性质。编程上闭包的概念可以类比的方式理解。

wts327的博客 2069

C#中的闭包

1、 闭包的含义 首先闭包并不是针对某一特定语言的概念,而是一个通用的概念。除了在各个支持函数式编程的语言中,我们会接触到它。一些不支持函数式编程的语言中也能支持闭包(如java8之前的匿名内部类)。 在看过的对于闭包的定义中,个人觉得比较清晰的是在《JavaScript高级程序设计》这本书中看到的。具体定义如下: 闭包是指有权访问另一个函数作用域中的变量的函数。 注意,闭包这个词本身指的...

qq_38461418的博客 579

C# 闭包详解

闭包是指在程序运行时能够记住并访问定义时的外部作用域中变量的函数。它具备两个核心特征:能作为第一类对象传递(头等函数)和能捕获自由变量。头等函数意味着函数可以作为参数传递给其他函数,也可以作为返回值。自由变量是指在闭包函数内部引用但是不在函数内定义的变量。闭包和委托机制不仅存在于 C# 中,许多现代编程语言都采用类似的设计来实现闭包功能。这种设计不仅仅帮助解决编程语言之间的语法差异,更重要的是提供了一种灵活和强大的编程工具,用于处理复杂的数据和控制流需求。

m0_74293254的博客 2093

理解C#中的闭包

1、 闭包的含义首先闭包并不是针对某一特定语言的概念,而是一个通用的概念。除了在各个支持函数式编程的语言中,我们会接触到它。一些不支持函数式编程的语言中也能支持闭包(如java8之前的匿...

dotNET跨平台 638

C#闭包 解析

C#闭包总结:闭包是Lambda或匿名函数捕获外部变量的机制,编译器会生成捕获类来保存变量。闭包常用于回调、LINQ等场景,能延长变量生命周期。案例分析展示闭包如何维护状态,不同闭包实例独立保存变量。特别注意循环中的闭包陷阱——多个闭包会共享同一变量引用,正确做法是在循环内创建变量副本。闭包捕获的是变量而非值,使用时需注意变量作用域问题。

weixin_45836091的博客 913

C#闭包原理

原文章地址https://kb.cnblogs.com/page/111231/   其实要提到闭包,我们还得先提下变量作用域和变量的生命周期。   在C#里面,变量作用域有三种,一种是属于类的,我们常称之为field;第二种则属于函数的,我们通常称之为局部变量;还有一种,其实也是属于函数的,不过它的作用范围更小,它只属于函数局部的代码片段,这种同样称之为局部变量。这三种变量的生命周期基本都可以用一句话来说明,每个变量都属于它所寄存的对象,即变量随着其寄存对象生而生和消亡。对应三种作用域我们可以这样说,

Victor_Li_的博客 427
上一篇: c# delegate
下一篇: 理解c#中的闭包
nodeathphoenix
博客等级 码龄16年 97粉丝 99原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值