`
f002489
  • 浏览: 270936 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

C# Delegate和Event

    博客分类:
  • C#
 
阅读更多
http://lile1983.blog.sohu.com/65073168.html


一.委托(Delegate):一种引用方法类型。
调用委托:调用方传递给委托的参数被传递给方法,来自方法的返回值(如果有)由委托返回给调用方。
    public delegate void Del(string message);
    // Create a method for a delegate.
    public static void DelegateMethod(string message)
    {
        System.Console.WriteLine(message);
    }
    // Instantiate the delegate.
    Del handler = DelegateMethod;
    // Call the delegate.
    handler("Hello World");
异步回调:由于实例化委托是一个对象,所以可以将其作为参数进行传递,也可以将其赋值给属性。这样,方法便可以将一个委托作为参数来接受,并且以后可以调用该委托。
    public void MethodWithCallback(int param1, int param2, Del callback)
    {
        callback("The number is: " + (param1 + param2).ToString());
    }
    MethodWithCallback(1, 2, handler);

二.事件(Event):C#中的事件处理实际上是一种具有特殊签名的delegate,象下面这个样子:
public delegate void MyEventHandler(object sender, MyEventArgs e);
其中的两个参数,sender代表事件发送者,e是事件参数类。MyEventArgs类用来包含与事件相关的数据,所有的事件参数类都必须从System.EventArgs类派生。当然,如果你的事件不含特别的参数,那么可以直接用System.EventArgs类作为参数。
结合delegate的实现,我们可以将自定义事件的实现归结为以下几步:
1:定义delegate对象类型,它有两个参数,第一个参数是事件发送者对象,第二个参数是事件参数类对象。
2:定义事件参数类,此类应当从System.EventArgs类派生。如果事件不带参数,这一步可以省略。
3:定义事件处理方法,它应当与delegate对象具有相同的参数和返回值类型。
4:用event关键字定义事件对象,它同时也是一个delegate对象。
5:用+=操作符添加事件到事件队列中(-=操作符能够将事件从队列中删除)。
6:在需要触发事件的地方用调用delegate的方式写事件触发方法。一般来说,此方法应为protected访问限制,既不能以public方式调用,但可以被子类继承。名字是可以是OnEventName。
7:在适当的地方调用事件触发方法触发事件。

下面是一个例子,例子模仿容器和控件的模式,由控件触发一个事件,在容器中捕捉并且进行处理。
事件的触发者:
/// <summary>
/// 事件的触发者
/// </summary>
public class Control
{
    public delegate void SomeHandler(object sender, System.EventArgs e);
    /**
     * 可以采用系统提供的System.EventHandler, 这里为了说明情况使用了自己定义的delegate
     * 如果需要在事件的参数中使用自己定义的类型,也要自己定义delegate
     */
    //public event System.EventHandler SomeEvent;
    public event SomeHandler SomeEvent;
    public Control()
    {
        //这里使用的delegate必须与事件中声名的一致
        //this.SomeEvent += new System.EventHandler(this.Control_SomeEvent);
        this.SomeEvent += new SomeHandler(this.ProcessSomeEvent);
    }
 
    public void RaiseSomeEvent()
    {
        EventArgs e = new EventArgs();
        Console.Write("Please input 'a':");
        string s = Console.ReadLine();

        //在用户输入一个小a的情况下触发事件,否则不触发
        if (s == "a")
        {
            SomeEvent(this, e);
        }
    }
 

    //事件的触发者自己对事件进行处理,这个方法的参数必须和代理中声名的一致
    private void ProcessSomeEvent(object sender, EventArgs e)
    {
        Console.WriteLine("hello");
    }
}

事件的接收者:

/// <summary>

/// 事件的接收和处理者

/// </summary>

class Container
{

    private Control ctrl = new Control();

 

    public Container()

    {

        //这里使用的delegate必须与事件中声名的一致

        //ctrl.SomeEvent += new EventHandler(this.OnSomeEvent);

        ctrl.SomeEvent += new Control.SomeHandler(this.ResponseSomeEvent);

        ctrl.RaiseSomeEvent();

    }

 

    public static void Main()

    {

        Container pane = new Container();

 

        //这个readline是暂停程序用的,否则画面会一闪而过什么也看不见

        Console.ReadLine();

    }

 

    //这是事件的接受者对事件的响应

    private void ResponseSomeEvent(object sender, EventArgs e)

    {

        Console.WriteLine("Some event occur!");

    }

}

程序运行的结果如下:

please input 'a':a

hello

Some event occur!

 

事件的应用

例如有下面的需求需要实现:程序主画面中弹出一个子窗口。此时主画面仍然可以接收用户的操作(子窗口是非模态的)。子窗口上进行某些操作,根据操作的结果要在主画面上显示不同的数据。我发现一些程序员这样实现这个功能:

主画面弹出子窗口后,将自己的指针交给子画面,然后在子画面中使用这个指针,调用主画面提供的方法,改变主画面上的数据显示。这样虽然可以达到目的,但是各个模块之间产生了很强的耦合。一般说来模块之间的调用应该是单方向的:模块A调用了模块B,模块B就不应该反向调用A,否则就破坏了程序的层次,加强了耦合程度,也使得功能的改变和追加变得很困难。

这时正确的做法应该是在子窗口的操作过程中发出各种事件,而由主窗口捕捉这些事件进行处理,各个模块专心的做自己的事情,不需要过问其他模块的事情。

事件的触发端:
  public partial class Delegate_Client : Form
    {
        public delegate void TextChangeHandler(object sender, EventArgs e);

        public event TextChangeHandler TextChangeEvent;

        public Delegate_Client()
        {
            InitializeComponent();
        }

        private void Delegate_Client_Load(object sender, EventArgs e)
        {
            this.TextChangeEvent += new TextChangeHandler(textBox1_textchanged);
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {
            TextChangeEvent(textBox1, e);
        }

        private void textBox1_textchanged(object sender, EventArgs e)
        {

        }
    }
事件的接收端:
  public partial class Delegate_Main : Form
    {

        public Delegate_Main()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Delegate_Client c = new Delegate_Client();
            c.TextChangeEvent += new Delegate_Client.TextChangeHandler(setText);
            c.Show();
        }
        public void setText(object sender, EventArgs e)
        {
            this.textBox1.Text = ((TextBox)sender).Text;
        }
    }
分享到:
评论

相关推荐

    C#中的事件和委托(Delegate,Event)

    在C#编程语言中,事件和委托是两个关键概念,它们是实现对象间通信和响应机制的核心工具。本文将深入探讨这两个概念,并提供详细的解释。 首先,我们要理解什么是委托(Delegate)。委托在C#中是一种类型,它代表了...

    C# Delegate小例子

    6. **事件(Event)和Delegate**: 在C#中,事件是委托的特殊使用,用于实现发布/订阅模式。类可以声明事件,其他类可以订阅这些事件以接收通知。事件通常通过私有委托类型实现,外部只能通过`add`和`remove`访问器...

    C#事件(event)使用方法详解

    事件(event)和委托(delegate)之间的关系可以通过一个浅显的比方来说明,委托(delegate) 就像房屋租赁中介,当你把租房子的消息告知中介后,中介就会产生出一套符合你要求的房屋租赁方案来。 事件(event)的实现: ...

    C#由浅至深深度解析Delegate委托与Event事件

    ### C#中的Delegate委托与Event事件深度解析 #### 引言 在.NET Framework中,委托(Delegate)和事件(Event)是非常重要的概念。对于初学者而言,这些概念可能较为抽象和难以理解。本文旨在通过一系列逐步深入的...

    delegate和event入门实例

    `Event`是C#中事件处理的实现方式,它基于`Delegate`。事件是一种通知机制,允许一个对象(事件发布者)通知其他对象(事件订阅者)关于特定情况的发生,而不暴露其内部状态。 1. **声明Event** - 在事件发布者的...

    C# 中委托和事件的例子DelegateAndEventDemo

    C# 中委托和事件的例子DelegateAndEventDemo 京华志&精华志出品 希望大家互相学习,互相进步 支持CSDN 支持微软 主要包括C# ASP.NET SQLDBA 源码 毕业设计 开题报告 答辩PPT等

    Delegate&Event

    在C#编程语言中,委托和事件是两个非常重要的概念,它们构成了.NET框架中的多线程和异步处理的核心机制。下面将详细讲解这两个概念及其应用。 **委托(Delegate)** 1. **定义与理解**:委托在C#中可以看作是指向...

    Delegate实现传值

    Delegate是事件处理、回调函数和多播委托的基础,是C#中的一个重要特性。在本示例中,“Delegate实现传值”主要探讨的是如何利用Delegate在两个界面上进行数据传递,尤其是从第二个界面向第一个界面传递数据。 在...

    C# Event小例子

    这个例子“C# Event小例子”将帮助我们深入理解事件的工作原理和使用方式。 事件是基于发布/订阅模式的,它允许类暴露通知机制,而不直接暴露底层的数据或行为。这样可以提高代码的封装性和可维护性。在C#中,事件...

    Event Bus C# 事件总线

    在C#编程中,事件总线(Event Bus)是一种设计模式,它允许应用程序的不同组件之间进行松耦合的通信。这种模式特别适用于大型项目或微服务架构,因为它们可以简化组件之间的交互,使得代码更易于维护和扩展。下面将...

    .net c# 动态 添加event

    根据提供的文件信息,可以看出文档与 .NET 和 C# 动态添加事件(Event)有关,但实际内容似乎并不涉及具体的编程细节,而是包含了大量看似不相关的符号和文本。因此,这里将基于标题和描述来详细阐述如何在 .NET 的 ...

    delegate与事件的实例(c#)

    在C#编程语言中,`delegate`和`事件(event)`是两个核心概念,用于实现基于对象的回调和发布/订阅模式。本文将通过一个简单的实例深入解析这两个概念,帮助初学者更好地理解和运用。 首先,`delegate`是C#中的一个...

    DelegateEvent04.zip

    本压缩包"DelegateEvent04.zip"包含了关于C#委托与事件的学习代码,帮助开发者深入理解这两种机制。 首先,我们来详细讲解一下C#中的委托。委托在C#中可以被视为类型安全的函数指针,它允许我们将方法作为参数传递...

    c#关于Event与委托的例子

    在C#编程中,事件(Event)和委托(Delegate)是两种非常重要的概念,它们是实现对象间通信的关键机制。事件通常用于一个类(发布者)通知其他类(订阅者)某一特定动作的发生,而委托则充当了函数指针的角色,允许...

    C#委托代码样例DelegateDemo

    在C#编程语言中,委托(Delegate)是一种强大的特性,它允许我们把方法作为参数传递,或者存储在变量中稍后调用。这种设计模式在处理事件处理、回调函数、异步操作等场景时尤为常见。本文将深入探讨C#中的委托以及其...

    CSharp_Delegate C#委托

    C# 3.0引入了匿名方法和Lambda表达式,使得无需预先定义方法即可直接在委托实例化时提供实现。这对于简单的回调或者临时性的功能非常方便。 ```csharp MyDelegate anonymousMethod = delegate(string msg) { ...

    C#事件处理和委托event delegate实例简述

    本文实例讲述了C#事件处理和委托event delegate,分享给大家供大家参考。具体方法如下: 以下仅仅是用最简单的方式表示事件,实际应用可能是不同窗体之间相互通知某些操作,达到触发。 首先声明一个degate的 ...

    c#中关于委托delegate的经典的实例

    在C#编程语言中,委托(Delegate)是一个强大的特性,它允许我们将方法作为参数传递给其他方法,或者存储和调用方法的集合。这个特性在事件处理、回调函数以及实现函数式编程风格时非常有用。在本文中,我们将深入...

    DelegateEvent

    在Windows Forms(Winform)应用程序开发中,常常需要在不同的窗体之间进行数据传递和交互。委托事件是一种常用的方法,可以有效地实现这种跨组件或对象的通信。本篇将详细讲解如何在Winform中利用委托事件来实现两...

Global site tag (gtag.js) - Google Analytics