定义:
委托是一种在对象里保存方法引用的类型,同时也是一种类型安全的函数指针。
理解委托的一种方式可以把委托的作用当作是给方法签名指定名称。
委托的定义类似于方法的定义,但没有方法体,定义的委托名前要加上关键字delegate。

因为定义委托基本上是定义一个新类,所以可以在定义类的任何地方定义委托,既可以在另一个类的内部定义委托,也可以在所有类的外部定义委托,还可以在命名空间中把委托定义为顶层对象。根据定义的可见性,可以在委托定义上添加一般的访问修饰符:public、private和protected等:

一个委托实例压缩(或者称为封装)了一个方法称之为“一个可调用的实体” ,所以“一个可调用的实体”也就由这个委托实例本身和实例中封装的方法组成

委托也可以包含多个方法,这种委托称为多播委托。

如果调用多播委托,就可以按顺序连续调用多个方法。为此,委托的签名就必须返回 void (否则,返回值应送到何处?)(当委托只包含一个方法的时候,其返回类型的声明可以参照所封装的方法,不一定必须是void)。实际上,如果编译器发现某个委托返回 void ,就会自动假定这是一个多播委托。

委托的优点:
(1)压缩方法的调用。
(2)合理有效地使用委托能提升应用程序的性能。
(3)用于调用匿名方法。
委托的声明:
作用域修饰符 delegate 委托返回类型 委托名();
如:public delegate  Void Test();

注意点:可以在不带参数或参数列表的情况下声明委托。应当遵循和声明方法一样的语法来声明委托.

委托的示例程序:

public delegate double Delegate_Prod(int a, int b);
class Class1
{
    static double fn_Prodvalues(int val1, int val2)
    {
        return val1 * val2;
    }
    static void Main(string[] args)
    {
        //Creating the Delegate Instance
        Delegate_Prod delObj = new Delegate_Prod(fn_Prodvalues);
        Console.Write("Please Enter Values");
        int v1 = Int32.Parse(Console.ReadLine());
        int v2 = Int32.Parse(Console.ReadLine());
        //use a delegate for processing
        double res = delObj(v1, v2);
        Console.WriteLine("Result :" + res);
        Console.ReadLine();
    }
}

解释:

上面我用一段小程序示范了委托的使用。委托Delegate_Prod声明时指定了两个只接受整型变量的返回类型。同样类中名为fn_Prodvalues的方法也是如此,委托和方法具有相同的签名和参数类型。
在Main方法中创建一个委托实例并用如下方式将函数名称传递给该委托实例:
Delegate_Prod delObj = new Delegate_Prod(fn_Prodvalues);
这样我们就接受了来自用户的两个值并将其传递给委托:
delObj(v1,v2);
在此委托对象压缩了方法的功能并返回我们在方法中指定的结果。
多播委托:
(1)多播委托包含一个以上方法的引用。
(2)多播委托包含的方法必须返回void,否则会抛出run-time exception。
多播委托的示例程序:
using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApp1
{

    //声明一个委托
    public delegate void msg();

    //编写一个类
    class messges
    {
        //messges类下的一个成员方法m1
        public static void m1()
        { Console.WriteLine("方法一被huashanlin调用"); }

        //messges类下的一个成员方法m2
        public static void m2()
        { Console.WriteLine("方法二被huashanlin调用"); }

        //messges类下的一个成员方法m3
        public static void m3()
        { Console.WriteLine("方法3huashanlin被调用"); }
    }

    //另一个类
    class Program
    {
        
        //该类下包含的主函数
        static void Main(string[] args)
        {
            //实例化一个委托,并封装messges类中的一个方法m2
            msg ms = new msg(messges.m2);

            //在原有的封装了一个m1方法的委托实例中再封装进一个新的方法m1
            ms = ms + messges.m1;
            //或者上面的语句可以写成ms += messges.m1;两者的效果是一样的

            //以下为该委托实例封装第三个方法
            ms += messges.m3;

            //调用该委托实例,那么由于多播委托之后调用该委托就要执行完此封装进去的三个方法
            ms();

        }
    }
}

//注:deletge保存的方法签名是以hash队列的形式存在的

多播委托示例程序二:

delegate void Delegate_Multicast(int x, int y);
Class Class2
{
static void Method1(int x, int y) {
  Console.WriteLine("You r in Method 1");
}
static void Method2(int x, int y) {
  Console.WriteLine("You r in Method 2");
}
public static void Main() 
{
  Delegate_Multicast func = new Delegate_Multicast(Method1);
func += new Delegate_Multicast(Method2);
      func(1,2);             // Method1 and Method2 are called
      func -= new Delegate_Multicast(Method1);
      func(2,3);             // Only Method2 is called
   }
}    
解析:
上面的示例程序分别定义了名为method1 和 method2的两个接受整型参数、返回类型为void的方法。
在Main函数里使用下面的声明创建委托对象:
Delegate_Multicast func = new Delegate_Multicast(Method1);
然后使用+= 来添加委托,使用-=来移除委托。

C#多播委托/多播代理的更多相关文章

  1. .net 多播委托的使用方法以及场景,更简单的观察者模式

    首先来说一下什么是多播委托 多播委托就是在委托里定义一个或者多个方法的一个集合 使用方法: public Action actList; //添加方法 public void AddActionMet ...

  2. 【C#进阶】多播委托和委托数组像是一回事~

    这个MathOperation类有三静态方法,参数都是double,并且没有返回值,考虑用Action<>() 这种预定义的委托哦 class MathOperations { publi ...

  3. 委托Delegate,多播委托和委托链

    定义一个委托 public delegate void CalculateDelegate(int 32 x,int 32 y); 定义一个委托类型的变量 public static Calculat ...

  4. C# 注销掉事件,解决多播委托链表的问题

    c#的事件是多播委托.当绑定多个事件时,事件会依次触发,清除掉注册的委托链表:方法1  C# Code  12345678910111213141516171819202122232425262728 ...

  5. 【小白学C#】谈谈C#多播委托因异常而终止的解决方案

    一.前言 前几天,马三在与朋友闲聊技术的时候,朋友忽然抛出一个问题,把马三难倒了,本着求知的精神,回来以后马三就查阅了相关资料并做了一些实验,终于把问题搞明白了,因此写下本篇博客记录一下.首先,问题是 ...

  6. C# 委托链(多播委托)

    委托既可以封装一个方法,又可以对同一类型的方法进行封装,它就是多播委托 using System; using System.Collections.Generic; using System.Lin ...

  7. 多播委托和匿名方法再加上Lambda表达式

    多播委托就是好几个方法全都委托给一个委托变量 代码: namespace 委托 { class Program { static void math1() { Console.WriteLine(&q ...

  8. ios多播委托

    在现实中回调的需求也分两种 一对一的回调. 一对多的回调. 对于一对一的回调,在IOS中使用delegate.block都能实现.而一对多的回调基本就是通知中心了. 假如现在有一个需求,我们以图片下载 ...

  9. 委托、多播委托(MulticastDelegate)

    委托.多播委托(MulticastDelegate) 多播委托(MulticastDelegate)继承自 Delegate ,表示多路广播委托:即,其调用列表中可以拥有多个元素的委托.实际上,我们自 ...

随机推荐

  1. django1.8中如何显示图片,应用css样式,javascript事件

    在django中将图片.javascript.css称为静态文件.如何将这些静态文件显示在django中呢?近期做一个项目,一直困扰着我,后来查找各种资源,终于在官方文档中找到. 官方文档链接 在se ...

  2. php将session保存到数据库的类实例(php版本需要大于5.4)

    这里实现了一个把session存储到数据库的类,包括数据表的创建.类的使用.php的配置. 可以更好地进行用户控制管理. 做项目的时候,有一个需求,是要实现禁止一个账号两处登录.同时要统计当前在线用户 ...

  3. mysql特殊语句学习

    一.Mysql ON子句和USING子句 Mysql 中联接SQL语句中,ON子句的语法格式为:table1.column_name = table2.column_name. 当模式设计对联接表的列 ...

  4. MySQL索引经验

    在数据库表中,使用索引可以大大提高查询速度. 假如我们创建了一个testIndex表:create TABLE testIndex(i_testID INT NOT NULL,vc_Name VARC ...

  5. ps减去图层混合模式

    ps减去图层混合模式 CMYK 1.1.青色作为基色,品红作为混合色(减去混合模式) 红反即青色(绿色+蓝色) - 绿反即品红色(红色+蓝色)= 绿色   公式简化: 绿色 + 蓝色 - 红色 - 蓝 ...

  6. 算法练习:最小生成树 (Minimum Spanning Tree)

    (注:此贴是为了回答同事提出的一个问题而匆匆写就,算法代码只求得出答案为目的,效率方面还有很大的改进空间) 最小生成树是指对于给定的带权无向图,需要生成一个总权重最小的连通图.其问题描述及算法可以详见 ...

  7. mysql部分学习心得(入门级别)

    mysql中针对不同的数据选择对应的存储引擎 mysql中也会针对不同的数据处理选择对应的存储的引擎 mysql中也会针对不同的数据处理选择对应的存储的引擎 mysql中一些授权(grant)等的通常 ...

  8. 深入理解php 匿名函数和 Closure

    而在PHP 5.3发布的时候, 其中有一条new feature就是支持闭包/Lambda Function, 我第一反应是以为zval新增了一个IS_FUNCTION, 但实际上是构造了一个PHP ...

  9. 给class添加id封装

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  10. java.lang.NoClassDefFoundError: Ljavax/enterprise/inject/spi/BeanManager;

    java.lang.NoClassDefFoundError: Ljavax/enterprise/inject/spi/BeanManager; 删除Struts2-cdi-plug 的插件的jar ...