C# Event--Anonymous Methods

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

Anonymous methods are another improvement of the next generation of C#. They allow you to declare methods in the context of their use and without naming them.

Listing 1-12 demonstrates the use of anonymous methods within an ASP.NET page. During Page_Load an anonymous event-handling method is assigned to a Button control. The method will change the text of the Label control, which is also placed on the page.



Listing 1-12:
Assigning and Handling Events Right Away

  1. void Page_Load (object sender, System.EventArgs e)
  2. {
  3.    this.Button1.Click += delegate(object dlgSender, EventArgs dlgE)
  4.    {
  5.      Label1.Text = "Yeah, you clicked the button!";
  6.    };
  7. }

What's new is that you can abandon an explicit notation of the event-handling method—as long as it's useful! Just put the code after the assignment of the delegate. Open a new scope after the delegate keyword by using a brace, enter the desired actions, and close the scope with another brace. Then you finish the whole statement with a semicolon.

Unlike what is being demonstrated in the previous example, you can use more than one line of code, of course. In doing so, you have access to the two common event parameters that have to be defined explicitly as you assign the delegate. Please notice that I've renamed these parameters to avoid a conflict with the ones for the Page_Load event.

Even if it looks somewhat unusual at first sight, it's possible to use the local variables of the outer scope within the anonymous method. According to this, the lines in Listing 1-13 are correct, although they aren't arranged very clearly.



Listing 1-13: Accessing Variables Declared in the Upper Scope


  1. void Page_Load (object sender, System.EventArgs e)
  2. {
  3.    string text = "Yeah, you clicked the button!";
  4.    this.Button1.Click += delegate(object dlgSender, EventArgs dlgE)
  5.    {
  6.       Label1.Text = text;
  7.    };
  8. }


Anonymous methods may be used with more than one event or even in a completely different way. If you want to, you can reference the delegate in a variable and handle it as usual, as Listing 1-14 shows.


Listing 1-14: Using the Delegate As Usual

   
  1. void Page_Load (object sender, System.EventArgs e)
  2. {
  3.    EventHandler handler = delegate(object dlgSender, EventArgs dlgE)
  4.    {
  5.       Label1.Text = "Yeah, you clicked the button!";
  6.    };
  7.    this.Button1.Click += handler;
  8.    this.Button2.Click += handler;
  9. }

Internally, the C# compiler converts the anonymously implemented method into a class including a uniquely named method. The created delegate now points to this procedure. In real life, the usage of anonymous methods is particularly of interest with regard to smaller event-handling methods. For the sake of clarity, you should not overuse this method, particularly in combination with longer routines.

Another area you could apply such methods might be multithreading. Until now, an explicit method was required to start a new thread. In this particular case, the anonymous counterpart can provide even more clarity because the context becomes more obvious. In Listing 1-15, an approach based on a console application is exemplified. In this case, the dynamic method is directly passed in the constructor of the Thread class. This looks really funny, but it actually works!


Listing 1-15: The Entry Code for the Second Thread Passed As an Anonymous Method


    
  1. using System;
  2. using System.Threading;
  3. namespace MyLittleConsoleApp
  4. {
  5.    public class MainClass
  6.    {
  7.       [STAThread]
  8.       static void Main()
  9.       {
  10.          Thread myThread = new Thread(delegate()
  11.          {
  12.             for(int i = 0; i < 20; i++)
  13.             {
  14.                Console.WriteLine("Working thread ...");
  15.                Thread.Sleep(500);
  16.             }
  17.          });
  18.          myThread.Start();
  19.          for (int i = 0; i < 10; i++)
  20.          {
  21.             Console.WriteLine("In main.");
  22.             Thread.Sleep(1000);
  23.          }
  24.          Console.Read();
  25.        }
  26.    }
  27. }

转自:<<ASP.NET 2.0 Revealed>> Chapter 1
        What's New in C# 2.0?
C#C#高级语法 C#C#高级语法 1、特性(Attribute): 用于添加元数据。在运行时传递程序中各种元素(比如类、方法、结构、枚举、组件等)的行为信息的声明性标签。您可以通过使用特性向程序添加声明性信息。 预定义特性:AttributeUsage;Conditional;Obsolete 自定义特性:一个新的自定义特性应派生自System.Attribute类。 2、反射(Refl 阅读详情

相关推荐

C#工业机器视觉软件架构设计:从能运行的Demo到能够稳定跑产线的软件

本文总结了工业机器视觉软件开发中的核心挑战,指出算法并非难点,真正关键在于系统架构与工程化设计。作者基于C#、VisionPro、HALCON等平台经验,提出分层架构、接口抽象、异步队列、解耦采集与处理、限长队列、异步存图、合理日志、业务与算法分离、配方管理等12项实践建议,强调软件工程能力对系统稳定性的重要性。最终结论:一套可靠工业视觉软件,算法仅占30%,其余70%取决于架构设计与工程实现。

XiaoZhenHua98|工业机器视觉开发 368

C#委托进阶:Action/Func与柯里化实战指南

C#编程中,委托作为类型安全的函数指针,是实现回调、事件处理和函数式编程的核心机制。其原理是通过定义方法签名模板,允许将方法作为参数传递或赋值给变量,从而实现了代码的灵活解耦。这一技术价值在于提升了代码的模块化和可复用性,尤其在处理异步操作、事件驱动架构以及LINQ查询等场景中不可或缺。随着语言发展,匿名方法和Lambda表达式进一步简化了委托的使用,而泛型委托Action和Func则标准化了常见函数签名的声明。在这些基础之上,柯里化技术通过将多参数函数转化为单参数函数链,实现了参数复用和函数组合,为构建

weixin_30482383的博客 416

java中事件监听器

Timer组件实现定时器功能,一个Timer对象,每隔delay时间,执行AtionEvent事件。Timer类声明如下:public class Timer implements Serializable { public Timer(int delay,ActionListener listener) //delay设置延时时间,listener指定事件处理对象 public v

green703338130的博客 1906

HsMod插件架构深度解析:基于BepInEx的32倍速加速引擎与模块化设计实现

HsMod是一款基于BepInEx框架开发的炉石传说高性能插件,通过创新的内存补丁技术和多线程优化算法,实现了最高32倍速的游戏加速引擎。该插件采用模块化架构设计,集成了Harmony运行时补丁、动态配置管理和Web服务接口,为中级开发者和技术用户提供了完整的游戏修改解决方案。 HsMod的核心技术架构建立在BepInEx 5.4.23.2插件框架之上,通过C#反射和IL代码注入技术实现对Uni

gitblog_01145的博客 718

基于C#开发的ScreenSaver屏保应用 - 开源研究系列文章 - 个人小作品

,然后在泡泡屏保里就说在其基础上集成其它的屏保文件,做成自己屏保小应用,让其它屏保能够得到应用,于是就找了一些屏保,放到了此屏保应用里用于选择,打造自己的屏保管理应用,于是就有了此文。将插件放在应用的PlugIns目录里,运行应用,在设置里选择屏保,等待运行。(就是将屏保文件集成到插件Dll文件里进行调用)这个例子只是抛砖引玉,请需要的读者自己复用代码。上次编写了图片屏保(1) 主应用监控倒计时;

lzhdim的专栏 264

C# .NET 周刊 |2026 年 8 月 4 期

本文介绍了用 C#、WinForm、WebView2、HTML 和 CSS 构建管理系统界面的方案。它强调用 WebView2 连接原生窗体和网页界面,实现数据传递、事件通知和样式切换,适合用户、权限、日志、报表等常见后台场景。方案思路清晰,实用性较强,但技术深度和原创细节一般,缺少实现代码和性能分析。

InCerry的博客 292

Statements without Semicolons

一条物理行 = 多条语句,完全合法;对比:Python 靠缩进和换行区分语句,C# 完全靠分号,这就是 “free-form 语言” 的特征。同样地,有些情况 —— 例如 using 声明 —— 虽然带有分号作为后缀,但它并不是一条语句。例如,代码清单 1.3 在一行里包含两条语句,两者结合,分别在两行中显示 Up 和 Down。由于换行并不分隔语句,你可以把多条语句写在同一行,C# 编译器会把这行解释为包含多条指令。实际上,代码块本身也被视为语句(代码块同样由语句组成),而且它们不需要以分号结尾。

龙山大佛爷的博客 188

外贸独立站SEO优化全攻略:从0到1的完整指南

外贸独立站SEO是低成本获取精准海外流量的关键。本文系统梳理完整优化框架:从关键词研究(核心词与长尾词筛选)、站内优化(标题/URL/内链)、技术优化(HTTPS/速度/移动端/结构化数据),到内容营销、外链建设及本地化多语言策略,并涵盖数据监测与持续优化,助你建立系统化SEO知识体系。

2601_96764108的博客 278

PDF浏览器(WPF C#

本PDF浏览器基于WPF C#与Vue3、TypeScript、PDF.js开发,支持多标签浏览、缩略图导航、文本高亮批注、页面旋转缩放及双击关联打开。新增15种语言切换、密码管理、历史记录功能,采用无文件落地设计提升安全性。支持明暗主题切换,单实例运行,操作简便。即将发布全功能免费版,持续优化中。

9.歌工作室 234

Lua 基础语法(六)xLua Lua 调用 C# 交互

Lua通过cs.前缀访问C#类、对象与组件,使用冒号调用实例方法,点号调用静态成员。创建对象无需new,可直接调用类名;支持ref/out多返回值、params可变参数及委托事件订阅。注意重载函数因Lua统一为number类型,可能受桥接注册顺序影响。底层依赖虚拟栈与Gen桥接文件实现跨语言交互,需手动生成并注入代码。关键点包括命名空间前缀、:与.区分、事件注册移除、虚拟栈原理及热更新机制。

2301_80252792的博客 439

C# UdpClient 单播 三种通信版本

UDP单播:一对一精准通信,数据只能发送给指定唯一IP+端口的设备,点对点专属数据交互。手动自定义本机IP、本机绑定端口手动输入对方IP端口,可与任意UDP设备通信通用性最强,适配所有UDP点对点通信场景。

2401_84677775的博客 307

基于 C# / .NET 8 + Windows Forms + SQLite 的桌面银行业务演示系统——华夏示范银行管理系统

华夏示范银行管理系统是一款基于C#/.NET8+WindowsForms+SQLite的桌面端业务演示系统,采用分层架构设计,支持超级管理员、管理员与客户三类角色。系统集成登录认证、顶部导航、客户/产品管理、持仓价值计算、操作日志双写(SQLite+文本)、空闲自动登出及数据导出功能。通过“内容控件+按钮栏”组合模式实现页面动态扩展,支持自定义页配置与灵活功能开关,具备高可维护性与可拓展性,适用于银行业务流程教学与原型验证。

weixin_66547608的博客 176

Lua 基础语法(七)xLua 完整热更新 Demo

本文详解xLua Hotfix热更新技术,涵盖[Hotfix]标签作用与性能风险、AB包打包配置、UnityWebRequest异步下载及进度条实现、自定义AddLoader加载器注册、Lua热修复C#方法流程,并通过完整Demo演示从点击生成Cube到热更为红色Sphere的全过程。重点解析同名资源踩坑、Hotfix注入失效、重载函数调用异常等高频问题,对比xLua与下一代Huatuo(HybridCLR)热更新方案,强调其能力边界与选型建议,助力开发者掌握热更新核心技能并落地实战。

2301_80252792的博客 388

手写观察者模式:C#上位机状态通知的优雅解法

定义:定义对象间一种一对多的依赖关系,当一个对象状态改变时,所有依赖它的对象都会收到通知并自动更新。两个核心角色:角色别名职责Subject​主题 / 被观察者 / 发布者维护观察者列表,提供注册/注销,状态变化时通知Observer​观察者 / 订阅者定义接收通知的接口(Update 方法)注册(Attach)→ 变化 → 通知(Notify)。观察者模式的本质,是把"谁关心我变了"这个问题,从「编译期硬编码」变成「运行期动态注册」。简单场景用event(语言级、够用);

A_nanda的博客 468

Lua 基础语法(四)C# 原生交互(LuaInterface)

LuaInterface是C#与Lua互调桥梁,含两个dll,已停维护但适合理解热更新原理。C#通过LuaEnv执行Lua字符串或文件,读取变量、调用函数、遍历表;Lua可用LuaNet加载C#程序集,访问实例(冒号)与静态成员(点号)。热更新核心:仅替换Lua脚本,C#无需重编译。

2301_80252792的博客 328

c#软件开发学习笔记--WPF(MVVM框架)

概念:区域(Region)是 Prism 中用来「动态容纳视图」的占位容器,替代传统<Frame>。你负责把视图放进去,展示的位置由区域决定。定义方式:在 XAML 中用附加属性prism:RegionManager.RegionName="区域名"标记某控件为区域(常用于):打开方式(两种)视图注入(固定投放)——启动时直接把视图放进来,之后不切换:_m = m;_m = m;

Z599817841的博客 347

Unity · 性能优化:内存管理完全指南:从托管堆到跨桥开销

在 Unity 中,托管内存(C# 对象)与本机内存(引擎对象) 之间存在频繁的数据交换。这种跨越两个内存域的操作,被称为“跨桥”(Crossing the Bridge)。本机部分:场景中的 GameObject、Transform、Mesh、Texture 等,其核心数据存储在本机内存中。托管部分:我们在 C# 中持有的引用(如 Transform变量),实际上是一个托管包装器(Wrapper),它指向本机对象,但自身只占很少的内存。

gghhb12的博客 362

基于C#实现(WinForm)文件管理系统

本项目主要使用了两种主要的数据结构。首先是C# WinForm所内置的TreeView树结构,主要用来实现项目的目录树。另一种是自定义的森林结构,用来存放文件系统中的所有文件夹和文本文件,以及它们之间的对应关系。以下是自定义结点的部分定义。//左孩子//右兄弟//父结点//当前结点的信息左侧为文件系统目录结构树,以树型结构展示出了所有的文件夹以及文本文件。右侧是一些选项栏,可以进行格式化、新建文件夹等操作,同时可以看到程序目前的总块数和已用块数、

神仙别闹的自留地 181
上一篇: 用SQL Server Profiler 调试脚本
下一篇: XPath 函数大全
broze
博客等级 码龄26年 48粉丝 94原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值