zoukankan      html  css  js  c++  java
  • C#之委托(一)

    1,什么是委托

    简单来说,就是代码在恰当的时间执行一段操作。代码不需要操作的细节。举个例子,遗嘱为例。一般来说遗嘱是在某人去世之前写好,然后把它放发到一个安全的地方,去世之后然后律师会执行遗嘱中的指令。

    2,简单委托的构成

    一个完整的能执行的委托必须满足4个条件:

    1,声明委托类型。

    2,必须创建一个委托的实例。

    3,必须有一个方法包含了要执行的代码。

    4,必须调用invoke执行委托。

    2.1 声明委托

    声明委托类型其实相当于创建一个类。其实也只是规定了实例操作需要的参数列表和返回值。

    image

    代码中声明了一个委托,delegate代表声明的是个委托类型,返回值是void(空),参数是一个String。其实重要的是在类型查看器里面新建的委托是继承MulticastDelegate的。而后者继承Delegate。所以将基类的一些方法传递给实例。

    2.2,创建一个委托实例

    可以想创建类一样创建委托,只是在初始化的时候需要传入一个方法。

                stringProcessor proc1, proc2;
                proc1 = new stringProcessor(StaticMethodes.Printstring);
                proc2 = new stringProcessor(Instance.Printstring);

    如果是静态方法,直接调用方法即可。如果是实例方法,必须创建类型。

    2.3,创建要执行的方法

    方法的要求只要和定义委托中拥有相同的签名。就是有相同的返回值和参数类型。下面列出两个方法签名。

            void Prinstring(string x);
            void PrintObject(Object X);

    第一个方法签名完全符合没什么问题,有趣的是第二个因为String是从Object中派生的。其实在C#1中是要求委托参数必须一致。但在c#2中有了改善。这个我们后面在说。然后只要把方法传到第二步创建的委托实例中就可以完成委托的声明了。

    2.4,调用委托

    最后一步就是调用委托了,只要调用委托实例的一个方法(Invoke)就可以了。

    proc1.Invoke("Hello");

    现在尝试写一个完整的例子,然后和输出结果看一下有什么特点。

    delegate void stringProcessor(string input);
    
        class Person
        {
            string name;
            public Person(string name)
            {
                this.name = name;
            }
            //声明实例方法
            public void Say(string message)
            {
                Console.WriteLine("{0} say: {1}", name, message);
            }
        }
    
        class Background
        {
            public static void Note(string note)
            {
                Console.WriteLine("note:{0}", note);
            }
        }
        class Program
        {
    
            //自定义事件
            static void Main(string[] args)
            {
                Person jon = new Person("Jon");
                Person tom = new Person("Tom");
    
                stringProcessor jonvoice = new stringProcessor(jon.Say);
                stringProcessor tomvoice = new stringProcessor(tom.Say);
                stringProcessor background = new stringProcessor(Background.Note);
    
                jonvoice("Jon");
                tomvoice.Invoke("Tom");
                background("ddddd");
    
                Console.ReadKey();
            }
        }

    上面例子分别调用了实例方法和静态方法。在最后调用的时候,可以使用invoke的显示调用,也可以使用C#的简化形式。其实委托的意义就在于增加了代码的灵活性,将方法抽象出来。想象一下,如果你想在点击按钮之后反生某事,而且不想对按钮本身的代码进行修改。只希望可以在按钮的事件掉用完之后调用下自己的代码。委托就是完成了这种操作。现在我们看看如果多个委托合并到一块。也就是我们常说的多播委托。

    3,合并和删除委托

    在第二部分的时候说过所有的委托都是基础System.Delegate的,Delegate中有两个静态的方法Combine和Remove,用来对委托的实例进行删除和添加实例。在这里说名一下,委托的不易变的。这里的Combin和Remove调用之后会产生一个全新的委托实例。是通过+=或者-=来实现Combine和Remove的方法调用的。

    委托的介绍就先到这里,以后还会说一下事件和委托的差别,lambda的运用,也会会提到其他一些关于委托的知识点。

  • 相关阅读:
    docker从容器里面拷文件到宿主机或从宿主机拷文件到docker容器里面
    maven构建的项目相关的命令
    gradle build文件中文乱码解决
    adobe acrobat看PDF文档显示字体发虚,有毛刺的解决办法
    Jenkins 用Tomcat部署War出现 反向代理设置有误
    变量 $cfg['TempDir'] (./tmp/)无法访问。phpMyAdmin无法缓存模板文件,所以会运行缓慢。
    phpMyAdmin配置文件中的密文(blowfish_secret)太短
    phpmyadmin报错:mysqli_real_connect(): (HY000/2002): No such file or directory 错误正确解决方法
    Gradle编译设置编码格式
    redis中的hash
  • 原文地址:https://www.cnblogs.com/shaoqi/p/6351282.html
Copyright © 2011-2022 走看看