委托学习笔记1:委托的基本使用

一、引子

在正式说委托前,我先给一个例子,然后引出后面要说的委托。

很简单,就是一个机器人打招呼的。

代码清单1.1:

    class Robot
    {
        public void GreetByChinese(string name)
        {
            Console.WriteLine("你好," + name + "!");
        }
        public void GreetByEnglish(string name)
        {
            Console.WriteLine("Hello," + name + "!");
        }
        //打招呼
        public void DoGreet(string name,string lang)
        {
            switch (lang)
            {
                case "chinese":
                    GreetByChinese(name);
                    break;
                case "english":
                    GreetByEnglish(name);
                    break;
                default: break;
            }
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            //实例化机器人对象
            Robot robot = new Robot();
            string name = Console.ReadLine();
            robot.DoGreet(name,"chinese");
            robot.DoGreet(name,"english");
            Console.Read();
        }

    }

代码清单1.1中创建了一个机器人类,类中封装了两个打招呼的方法和一个调用这两个方法的公共方法。DoGreet方法中,只要带name和switch中的条件,就可以打印出对应语言打招呼的语句。

那么,如果我要增加其他的语言,如法语、日语、韩语等,我除了增加对应的方法,还需要改DoGreet方法里的case语句,维护量较大。那有什么办法可以解决这种尴尬呢?

一种比较简单的方法是,直接将方法作为参数(变量),传给另一个方法(DoGreet),在其中执行即可。

但我们都知道,能作为方法的参数的是某一类型的对象或变量,而方法是个什么类型呢?确实找不出方法对应的类型。但依然有种方法可以间接的将方法作为一个参数来使用,这便引出了,下面要提到的“委托”。

二、关于委托,微软给出的定义如下:

“委托用于将方法作为参数传递给其他方法。”

早在C#1.0时,就已开始支持这个特性(用过VS2003的园友,应该是最清楚不过了)。关于微软给出的定义,已经很好理解了:我们利用委托,把方法作为一个参数(变量)传递给其他的方法,从而由其他方法来代为执行这个当做参数的方法里的动作。

三、那么怎么去使用委托呢?

使用委托,基本要按照如下步骤实现:

1、定义一个委托类型

访问修饰符 delegate 返回类型 委托类型名称(参数列表);

Ex:public delegate void Greet(string name);

2、创建一个执行某动作的方法(返回类型和参数列表须与委托类型相同)

访问修饰符 返回类型 方法名称(参数列表){......}

Ex:public void GreetByChinese(string name)

{

Console.WriteLine(“你好,”+name+“!”);

}

3、实例化委托类型

委托类型名称 委托对象名称=方法名称;

Ex:Greet greet=GreetByChinese;

4、开始使用,执行操作

委托对象名称(参数列表);

或:委托对象名称.Invoke(参数列表);

Ex:greet(“季节旋风”);  或:greet.Invoke(“季节旋风”);

如上,就这么个简单的流程,是不是很简单。但这里,可能有人会说,定义中不是将方法作为参数传给另一个方法吗?怎么没有这么用?其实这个不用担心,我们已经在步骤3中将方法引用给了greet对象,既然是对象,那么久可以作为方法的参数,就可以很好地解决这个疑问。

具体的看下面的代码清单3.1:

    //一个常用的委托,打招呼
    delegate void Greet(string name);
    //一个机器人类,封装打招呼
    class Robot
    {
        public void GreetByChiness(string name)
        {
            Console.WriteLine("你好," + name + "!");
        }
        public void GreetByEnglish(string name)
        {
            Console.WriteLine("Hello," + name + "!");
        }
public void GreetByJapaness(string name)
{
Console.WriteLine("こんにちは," + name + "!");
}
        //打招呼
        public void DoGreet(string name, Greet greet)
        {
            greet(name);
        }
    }
    class SampleDelegate
    {
        static void Main(string[] args)
        {
            //实例化机器人对象
            Robot robot = new Robot();
            string name = Console.ReadLine();
            //通过把方法作为变量来实现打招呼
            robot.DoGreet(name, robot.GreetByChiness);
            robot.DoGreet(name, robot.GreetByEnglish);
robot.DoGreet(name, robot.GreetByJapaness);
            Console.Read();
        }
}

执行结果如下:

依然是机器人大招呼的例子,但用到了委托,这样一来是不是更简洁了?这里已经可以轻松地将方法作为参数传递给执行方法(DoGreet)中,并在其中执行操作。

四、合并委托(多路广播委托)

委托对象的一个有用属性是:可以使用 “+” 运算符将多个对象分配给一个委托实例。 多播委托包含已分配委托的列表。 在调用多播委托时,它会按顺序调用列表中的委托。 只能合并相同类型的委托。 “-” 运算符可用于从多播委托中移除组件委托。

依然用机器人打招呼的例子来讲,这里就不再使用DoGreet方法了,直接在Main方法中来做“打招呼”动作。如下(代码清单4.1):

Greet greet = robot.GreetByChiness;
greet += robot.GreetByEnglish;
greet += robot.GreetByJapaness;
greet(name);

在运行时,它会按顺序执行调用的方法,如下图:

值得注意的是,只有对委托对象greet初始化后才可进行多播操作,例如下面的这种写法就是错误的:

Greet greet+= robot.GreetByChiness;

在执行移除(“-”)操作时,跟合并操作类似,但它是从委托中移除已有的方法。例如将代码清单4.1的代码后面加上,下面代码(代码清单4.2):

Console.WriteLine("移除日语后:");
greet -= robot.GreetByJapaness;
greet(name);

那么第二次greet时,会少一个日语问候,执行结果如下图:

时间: 2024-08-23 05:10:33

委托学习笔记1:委托的基本使用的相关文章

委托学习笔记后续:泛型委托及委托中所涉及到匿名方法、Lambda表达式

引言: 最初学习c#时,感觉委托.事件这块很难,其中在学习的过程中还写了一篇学习笔记:委托.事件学习笔记.今天重新温故委托.事件,并且把最近学习到和委托相关的匿名方法.Lambda表达式及泛型委托记录下来,以备复习使用. 委托: 日常工作中,常常见到委托用在具体的项目中.而且委托使用起来相对来说也是非常简单的,下面列举一个委托实例用以说明如何使用委托,代码如下: class Program { public delegate int CalculateDelegate(int x, int y)

C# 委托学习笔记

接触委托 代理 delegate很久啦.除了看API,Kotoba也给我讲了 .说到委托,拿下面这个小例子比较好.(14年6月26花花给我的练习) 实例:写一个方法A,定义个方法B(打印hello),和方法C(打印world),其中我只允许调用方法A.实现,1秒后打印出hello,3秒后打印出world. 先说一下回调的好处: 在开发中我们有些代码呢,是很固定的,但又有一些东西很灵活很容易发生变动.先假设B和C都不是我们自己写的,而是其他人已经写好的其他方法,所以我们在无BUG的情况下,尽可能不

JS和JQuery中的事件委托 学习笔记

事件委托其实并不是一个很高级的技巧,比如在一个页面里面,当只存在两个按钮的时候,可能你给按钮添加监听是这样的:(本文不考虑浏览器兼容性,关于事件的兼容性可参考前面的学习笔记) <div id="container"> <button id="btn1">按钮1</button> <button id="btn2">按钮2</button> </div> var btn1 =

[读书笔记]C#学习笔记二: 委托和事件的用法及不同.

前言:  C#委托是什么 c#中的委托可以理解为函数的一个包装, 它使得C#中的函数可以作为参数来被传递, 这在作用上相当于C++中的函数指针. C++用函数指针获取函数的入口地址, 然后通过这个指针来实现对函数的操作. 委托的定义和方法的定义类似, 只是在定义的前面多了一个delegate关键字. 正文: 委托可以被视为一个更高级的指针,它不仅仅能把地址传指向另一个函数,而且还能传递参数,返回值等多个信息. 系统还为委托对象自动生成了同步,异步的调用方式,开发人员使用BeginInvoke,E

《C#高级编程》之委托学习笔记 (转载)

全文摘自 http://www.cnblogs.com/xun126/archive/2010/12/30/1921551.html 写得不错,特意备份!并改正其中的错误代码..     正文: 最近在学C#的委托,通过网络的资料和书籍,现在总结如下: 回调(Callback)函数是windows编程的一个重要部分.回调函数实际上是方法调用的指针,也成为函数指针,是一个非常强大的编程特 回调(Callback)函数是windows编程的一个重要部分.回调函数实际上是方法调用的指针,也成为函数指针

JavaScript 学习笔记— —事件委托

<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> <script type="text/javascript"> //事件委托:利用冒泡的原理,把事件加到父级上,触发执行效果 //好处 //1.提高性能 //2.新添加的元素,还会有之前的事件 //event

c#学习笔记03——委托和事件

委托:一种引用类型,这种类型可以用来定义方法签名,从而使用委托实现将方法作为参数传递给其他方法.类似于C++中的函数之争,使用委托使程序员可以将方法引用封装在委托对象内. 定义和声明委托: 1 delegate 返回值 委托名(参数列表); 2 eg: 3 public delegate void SayHelloDelegate(string name); 使用委托:委托其实通过返回值和参数列表来定义方法和签名.任何与委托具有相同返回值和参数列表(签名)的方法都可以赋给该委托. 1 publi

C#学习笔记(委托)

委托的定义 委托(delegate)是一种可以把引用存储为函数的类型.这听起来相当的棘手,但是机制是非常简单的.委托的声明非常类似于函数,但是不带函数体,且要使用delegate关键字.委托的声明指定了一个返回类型和一个参数列表. 在定义了委托后,就可以声明该委托类型的变量.直接把这个变量初始化为与委托相同返回类型和参数列表的函数引用.之后,就可以使用委托变量调用这个函数,就像该变量是一个函数一样. 有了引用函数的变量之后,还可以执行不能用其他方式完成的操作.例如,可以把委托变量作为参数传递给一

C#委托与事件学习笔记

今天跟随视频学习了一下C#中最重要的一些概念之委托与事件.老杨的视频讲的还是挺深入浅出,不过刚接触C#.NET的人还是朦朦胧胧,就像张子阳先生说的"每次见到委托和事件就觉得心里别(biè)得慌,混身不自在".跨过这道坎的人就有种一览众山小的感觉了.我又浏览了皱华栋老师JamesZou的博文<深入理解C#委托及原理>(地址:http://www.cnblogs.com/jameszou/archive/2011/07/21/2112497.html),以及张子阳Jimmy Z