C#委托

版权声明:本文为博主原创文章,未经博主允许不得转载,详情访问:happysneaker.com https://blog.csdn.net/Cody_Ren/article/details/79965186

详情访问 Unity那些事儿happysneaker.com

一、委托的作用是什么?有什么优势值得我们来使用?

C# 委托实际上类似于C++中的函数指针,因为C#中不存在指针,所以用委托可以完成一些原来在C++中用函数指针完成的操作,例如传递一个类A的方法m给另一个类B的对象,使得类B的对象能够调用这个方法m。但与函数指针相比,委托有许多函数指针不具备的优点:

1、函数指针只能指向静态函数,而委托既可以引用静态函数,又可以引用非静态成员函数。在引用非静态成员函数时,委托不但保存了对此函数入口指针的引用,而且还保存了调用此函数的类实例的引用。
2、与函数指针相比,委托是面向对象、类型安全、可靠的受控(managed)对象。也就是说,runtime能够保证delegate指向一个有效的方法,无须担心delegate会指向无效地址或者越界地址。

二、使用委托有哪些需要注意的地方?

“代理”(delegate)(代表、委托):“委托”是类型安全的并且完全面向对象的。
(1)在C#中,所有的委托都是从System.Delegate类派生的(delegate是System.Delegate的别名)。
(2)委托隐含具有sealed属性,即不能用来派生新的类型。
(3)委托最大的作用就是为类的事件绑定事件处理程序。
(4)在通过委托调用函数前,必须先检查代理是否为空(null),若非空,才能调用函数。
(5)在委托实例中可以封装静态的方法也可以封装实例方法。
(6)在创建委托实例时,需要传递将要映射的方法或其他委托实例以指明委托将要封装的函数原型(.NET中称为方法签名:signature)。注意,如果映射的是静态方法,传递的参数应该是类名.方法名,如果映射的是实例方法,传递的参数应该是实例名.方法名。
(7)只有当两个委托实例所映射的方法以及该方法所属的对象都相同时,才认为它们是想等的(从函数地址考虑)。
(8)多个委托实例可以形成一个委托链,System.Delegate中定义了用来维护委托链的静态方法Combion,Remove,分别向委托链中添加委托实例和删除委托实例。
(9)委托三步曲:
a.生成自定义委托类:delegate int MyDelegate();
b.然后实例化委托类:MyDelegate d = new MyDelegate(MyClass.MyMethod);
c.最后通过实例对象调用方法:int ret = d();

三、如何使用委托?或者说如何定义一个委托?

实现一个委托是很简单的,通过以下3个步骤即可实现一个delegate:
1.声明一个delegate对象,它应当与你想要传递的方法具有相同的参数和返回值类型。
声明一个代理的例子:
public delegate int MyDelegate(string message);
2.创建delegate对象,并将你想要传递的函数作为参数传入。
创建代理对象的方法:
1). MyDelegate myDelegate = new MyDelegate(实例名.方法名);
2). MyDelegate myDelegate = new MyDelegate(类名.方法名);
注:如果需要代理的方法是一个static静态方法的话,采用第2种方式,否则采用第1种方式。
3.在要实现异步调用的地方,通过上一步创建的对象来调用方法。
可以直接使用代理调用代理所指向的方法:
myDelegate(向方法传递的参数);

其他见代码吧!!!!

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

//委托是一种特殊的类型,用于引用方法
//定义委托需要用 delegate 关键字
//委托可以把方法当作参数来传递
//委托可以使用 + - 运算符合并/解除绑定委托

namespace learning
{
    // 定义委托 - 访问修饰符 delegate 返回值类型 委托名(参数列表);相当于一种类型;
    public delegate void Something(string name);


    // 定义学生类
    public class Student {

        // 定义一个供老师调用的方法
        // 可以像普通类型一样当作方法参数传递
        public void Do(Something something) {
            // 但是方法最好不要写死了,所以可以定义一个委托
            // 可以像普通方法一样调用
            // 真正调用了方法 A - 方法回调
            something(name);
        }

        public Student(string name) {
            this.name = name;
        }
        private string name;
    }

    public class Teacher {
        public void Hungry() {
            Student s = new Student("老王");

            // 创建委托变量,括号里必须写一个已经实现了的方法
            Something a = new Something(A);
            Something b = new Something(B);
            Something c = a + b;

            // 委托对象可以使用 + - 来绑定/解除其他委托
            // 解除绑定
            c = c - a;
            s.Do(c);
        }

        // 参照委托的格式写
        public void A(string name) {
            Console.WriteLine("hello," + name);
        }
        public void B(string name) { Console.WriteLine(name + "paoshiquan"); }

    }

    class Program{

        public static void Main(string[] args)
        {
            Teacher t = new Teacher();
            t.Hungry();
        }
    }
}

这里写图片描述

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页