zoukankan      html  css  js  c++  java
  • C#1所搭建的核心基础(一)委托

    委托在某种程度上提供了间接的方法。换言之,不需要直接指定一个行为,而是将这个行为用某种方式“包含”在一个对象中。这个对象可以象其他任何对象那样使用。在这个对象中,可以执行封装的行为。可以将委托类型看做只定义了一个方法的接口,将委托的实例看做实现了那个接口的一个对象。

    委托的4个基本条件:

    1)声明委托类型;

    2)必须有一个方法包含了要执行的代码;

    3)必须创建一个委托实例;

    4)必须调用(invoke)委托实例。

     

    1.声明委托类型

    委托类型实际上只是参数类型的一个列表以及一个返回类型。它规定了类型的实例能表示的操作。以如下方式声明一个委托类型。

        delegate void StringProcessor(string input);

    这里的重点是StringProcessor其实是一个类型。它有方法,可以创建它的实例,并将引用传递给实例。

    2.为委托实例的操作找到一个恰当的方法

    找到(或者写)一个方法,它能做我们想做的事情,同时具有和委托类型相同的签名。

    来看看以下StringProcessor实例的5个备选的方法签名:

        void PrintString(string x)

        void PrintInteger(int x)

        void PrintTwoString(string x, string y)

        int GetStringLength(string x)

        void PrintObject(object x)

    我们来看,第一个方法完全符合要求,所以可以用它创建一个委托实例。第二个方法虽然也有一个参数但不是string类型,所以不兼容StringProcessor。第三个方法参数数量不匹配,所以不兼容。第四个方法有正确的参数列表,但是返回类型不是void(如果委托类型有返回类型,方法的返回类型也必须与之匹配)。第五个方法比较有趣,任何时候调用一个StringProcessor实例,都可以调用具有相同的参数的PrintObject方法,这是由于string是从object派生的。

    3.创建委托实例

    既然已经有了一个委托类型和一个有正确签名的方法,接着可以创建委托类型的一个实例,指定在调用委托实例时就执行该方法。至于具体用什么形式的表达式来创建委托实例,取决于操作使用实例方法还是静态方法。如果操作是静态方法,指定类型名称就可以了。如果操作时实例方法,就需要先创建类型(或者它的派生类型)的一个实例。这和平时调用方法是一样的。

    假定PrintString是StaticMethods类型中的一个静态方法,在InstanceMethods类型中是一个实例方法。下面是创建一个StringProcessor实例的两个例子:

        StringProcessor proc1, proc2;

        proc1=new StringProcessor(StaticMethods.PrintString);

        InstanceMethods instance=new InstanceMethods();

        prce2=new StringProcessor(instance.PrintString);

    4.调用委托实例

    这是很简单的事情(仅对同步调用而言)-调用一个委托实例的方法就可以了。这个方法本身被称为Invoke。在委托类型中,这个方法以委托类型的形式出现,并且具有与委托类型的声明中所指定的相同的参数列表和返回类型。调用Invoke会执行委托实例的操作,向它传递在调用Invoke时指定的任何参数。让我们看下下图更好的理解:

     

    下面来看一个完整的代码:

    using System;
    
    //声明委托类型
    delegate void StringProcessor(string input);
    
    class Person
    {
        string name;
        public Person(string name) { this.name = name; }
        //声明兼容的实例方法
        public void Say(string message)
        {
            Console.WriteLine("{0}说:{1}", name, message);
        }
    }
    
    class Background
    {
        //声明兼容的静态方法
        public static void Note(string note)
        {
            Console.WriteLine("({0})",note);
        }
    }
    
    class SimpleDelegateUse
    {
        static void Main()
        {
            Person jon = new Person("Jon");
            Person Tom = new Person("Tom");
            //创建3个委托实例
            StringProcessor jonsVoice, tomsVoice, background;
            jonsVoice = new StringProcessor(jon.Say);//实例方法
            tomsVoice = new StringProcessor(Tom.Say);//实例方法
    
            background = new StringProcessor(Background.Note);//静态方法
    
            //调用委托实例
            jonsVoice("Hello,World!");
            tomsVoice.Invoke("欢迎观临我的博客!");
            background("版权所有爱智旮旯!");
    
            Console.Read();
    
        }
    }

    效果如图:

     

  • 相关阅读:
    通过反射获取Android通知栏高度
    Android 的EditText实现不可编辑
    Android 代码混淆、第三方平台加固加密、渠道分发 完整教程(图文)
    eclipse、myeclipse,svn插件subclipse 忘记密码的解决方法(win7、win8、xp)
    Eclipse 基于接口编程的时候,快速跳转到实现类的方法(图文)
    WIN7、WIN8 右键在目录当前打开命令行Cmd窗口(图文)
    eclipse,myeclipse开发环境下,maven远程部署到tomcat7服务器(图文)
    python之路——博客目录
    生成器和协程 —— 你想知道的都在这里了
    python3.7导入gevent模块报错的解决方案
  • 原文地址:https://www.cnblogs.com/52net/p/2662125.html
Copyright © 2011-2022 走看看