惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

小众软件
小众软件
N
News and Events Feed by Topic
A
About on SuperTechFans
aimingoo的专栏
aimingoo的专栏
The Cloudflare Blog
H
Heimdal Security Blog
Schneier on Security
Schneier on Security
Engineering at Meta
Engineering at Meta
Google Online Security Blog
Google Online Security Blog
宝玉的分享
宝玉的分享
AI
AI
The GitHub Blog
The GitHub Blog
MongoDB | Blog
MongoDB | Blog
www.infosecurity-magazine.com
www.infosecurity-magazine.com
The Last Watchdog
The Last Watchdog
T
Troy Hunt's Blog
S
Security @ Cisco Blogs
H
Hacker News: Front Page
F
Fortinet All Blogs
博客园_首页
S
Secure Thoughts
N
News and Events Feed by Topic
P
Proofpoint News Feed
Microsoft Azure Blog
Microsoft Azure Blog
I
InfoQ
Spread Privacy
Spread Privacy
Hacker News - Newest:
Hacker News - Newest: "LLM"
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
Check Point Blog
Hugging Face - Blog
Hugging Face - Blog
Hacker News: Ask HN
Hacker News: Ask HN
C
CXSECURITY Database RSS Feed - CXSecurity.com
酷 壳 – CoolShell
酷 壳 – CoolShell
Stack Overflow Blog
Stack Overflow Blog
L
LINUX DO - 最新话题
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
S
Schneier on Security
Know Your Adversary
Know Your Adversary
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Scott Helme
Scott Helme
P
Privacy & Cybersecurity Law Blog
S
Securelist
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
O
OpenAI News
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
PCI Perspectives
PCI Perspectives
L
LangChain Blog
雷峰网
雷峰网
Security Archives - TechRepublic
Security Archives - TechRepublic
V2EX - 技术
V2EX - 技术

博客园 - 蹲在路边写代码

8000401a错误解决方案(Office Word,Excel,PowerPoit应用程序无法访问) SQL Server 2005 无法删除用户的解决方法 遍例指定目录及子目录下的所有文件添加进数据库 改善SQL语句的效率的几条原则,不断积累中 一些常用的WebServices 转Javascript的IE和Firefox兼容性汇编 - 蹲在路边写代码 - 博客园 转--使用 Request.QueryString 接受参数时,跟编码有关的一些问题 - 蹲在路边写代码 IE的showModalDialog与FireFox的window.open 父子窗口传值示例 三种常见选项卡效果 - 蹲在路边写代码 - 博客园 C#高级编程学习笔记(五)字符串与正则表达式 C#高级编程学习笔记(四) 内存管理和指针 SQL SELECT 语句完整的执行顺序 C#高级编程学习笔记(二)运算符和类型转换 C#高级编程学习笔记(-)C#基础 对象和类型 继承 构造函数和析构函数的原理及在C#中的运用(转载) CSS在IE与Firefox下的兼容性 CSS Hack 汇总 .NET的ORM工具SubSonic2.03的配置 ASP.NET的页面间传值方法 - 蹲在路边写代码 - 博客园
C#高级编程学习笔记(三)委托和事件
蹲在路边写代码 · 2008-03-26 · via 博客园 - 蹲在路边写代码

六、委托和事件

1、委托
委托是一个可以对方法进行引用的类。与其他的类不同,委托类具有一个签名,并且它只能对与其签名匹配的方法进行引用。
委托的类型是安全的,给定委托的实例可以表示任何类型的任何对象上的实例方法或静态方法--只要方法的签名匹配于委托的签名即可。
2、匿名方法
用作委托参数的一个代码块。
匿名方法中不能使用跳转语句跳到匿名方法外部,也不能从外部跳到匿名方法内部。
匿名方法内部不能访问不安全的代码。也不能访问在匿名方法外部使用的ref和out参数,但可以使用匿名方法外部定义的其他变量。
多播委托:可以按顺序连续调用多个方法。为此,委托的签名就必须返回void。
3、事件
事件是对象发送的消息,以发信号通知操作的发生。可以理解为一个或多个委托
使用委托的优点,委托和事件的区别和联系:
    C#中的委托类似于C或C++中的函数指针。使用委托使程序员可以将方法引用封装在委托对象内。然后可以将该委托对象传递给可调用所引用方法的代码,而不必在编译时知道将调用哪个方法。与C或C++中的函数指针不同,委托是面向对象,而且是类型安全的。
  C#中的“事件”是当对象发生某些事情时,类向该类的客户提供通知的一种方法。事件最常见的用途是用于图形用户界面;通常,表示界面中的控件的类具有一些事件,当用户对控件进行某些操作(如单击某个按钮)时,将通知这些事件。
  使用委托来声明事件。委托对象封装一个方法,以便可以匿名调用该方法。事件是类允许客户为其提供方法(事件发生时应调用这些方法)的委托的一种方法。事件发生时,将调用其客户提供给它的委托。
注明:委托是对方法的包装       在不确定要调用什么方法时候而又不能用抽象或者多态实现的时候用委托。
     比如一个button,当点击肯定要触发事件,做一些处理,如果你是这个控件的开发者,你怎么知道当点击是要处理什么?你这个button会被什么容器所包含?所以你必须公布一个event出去,用控件的人具体去实现其功能。 

参考:
         1、如下情况宜使用委托:
               只调用单个方法时.    
               当一个类需要方法说明的多重执行时.    
               期望使用静态方法执行规范时.    
               期望得到一个类似事件的模式时.    
               调用者无需知道无需获取定义方法的对象时    
               只想给少数既定组件分发执行规范时.    
               想要简单的组成结构时.    
          2、如下情况宜使用接口:  
                当规范定义了一组需要调用的相关方法时.    
                一个类仅代表性地执行一次规范时.    
                接口的调用者想映射接口类型以获取其他类或接口时
           3、对函数指针以.net的方式进行的封装,其实就是一个class。  
                应用最多的就是事件,在事件的情况下委托就变成了对回调函数指针的封装。 

看一个横刀天笑在写观察者模式的一个控制台程序例子:程序接收一个0到100之间整型的输入,程序接收到输入后开始一个从0到100的循环,当循环到你输入的数字的时候输出此数,并弹出窗口显示此数。

using System;
using System.Windows.Forms;

namespace Study
    
//定义一个委托,这里定义了观察者方法的签名,就是一个协议吧
    public delegate void NumberEventHandler(object sender, NumberEvantArgs e);
    
//要传递哪些参数到观察者?在这里定义,注意,要继承自EventArgs
    public class NumberEvantArgs : EventArgs
    
{
        
public NumberEvantArgs(int number)
        
{
            _number 
= number;
        }

        
private int _number;
        
public int Number
        
{
            
get return _number; }
            
set { _number = value; }
        }

    }

    
//观察者模式中的主题
    public class Subject
    
{
        
//定义一个事件,就是委托的实例
        public event NumberEventHandler NumberReached;
        
public void DoWithLoop(int number)
        
{
            
for (int i = 0; i <= 100; i++)
            
{
                    
//触发事件的条件到了 
                if (i == number)
                
{
                    NumberEvantArgs e 
= new NumberEvantArgs(i);
                    OnNumberReached(e);
                }

            }

        }

        
//注意,这个方法定义为保护的,虚拟的,代表子类还可以进行覆盖,改变触发事件的行为,甚至可以不触发事件
        protected virtual void OnNumberReached(NumberEvantArgs e)
        
{
            
//判断事件是否为null,也就是是否绑定了方法
            if (NumberReached != null)
                NumberReached(
this, e);
        }

    }

    
public class MainProgram
    
{
        
public static void Main()
        
{
            Console.WriteLine(
"Please intput a 0-100 number:");
            
int input=Int32.Parse(Console.ReadLine());
            
if (input < 0 || input > 100)
            
{ Console.WriteLine("Error"); }
            Subject s 
= new Subject();
            
//给事件绑定方法,静态的
            s.NumberReached += new NumberEventHandler(msgbox_NumberReached);
            MainProgram mp 
= new MainProgram();
            
//给事件绑定方法,实例方法
            s.NumberReached += new NumberEventHandler(mp.console_NumberReached);
            s.DoWithLoop(input);
            Console.ReadLine();
        }

        
void console_NumberReached(object sender, NumberEvantArgs e)
        
{
            Console.WriteLine(e.Number.ToString());
        }

        
static void msgbox_NumberReached(object sender, NumberEvantArgs e)
        
{
            MessageBox.Show(e.Number.ToString());
        }

    }

}

posted on 2008-03-26 15:10  蹲在路边写代码  阅读(465)  评论(0)    收藏  举报