浅学C#(8)——委托

版权声明:转载请注明出处 https://blog.csdn.net/le_17_4_6/article/details/86590592
委托

委托是函数的封装,它代表一类函数,它们都符合一定的签名:拥有相同的参数列表和返回值类型。同时,委托也可以看成是对函数的抽象,是函数的”类”。
此时,委托的实例将代表一个具体的函数。
一个委托声明、定义了一个引用类型可以用来封装具有一定签名的方法。一个委托实例可用来封装一个静态或实例方法。
一旦为委托分配了方法,委托将与该方法具有完全相同的行为。委托方法的使用可以像其他任何方法一样,具有参数和返回值
更加灵活的方法调用
用于异步回调
多线程编程中使用委托来指定启动一个线程时调用的方法

public delegate void ThreadStart();		//委托
static void DoCompress()	//方法实例
{
   //压缩代码
}
ThreadStart entryPoint = new ThreadStart(DoCompress);
Thread compressThread = new Thread(entryPoint);

委托应用——异步回调

异步回调:由于实例化委托是一个对象,所以可以将其作为参数进行传递,也可以将其赋值给属性。这样,方法便可以将一个委托作为参数来接受,并且以后可以调用该委托。这称为异步回调,是在较长的进程完成后用来通知调用方的常用方法。以这种方式使用委托时,使用委托的代码无需了解有关所用方法的实现方面的任何信息

using System;

delegate  bool  CompareOp(object  a, object  b);	//声明委托类型
class BubbleSorter
{
    static public void Sort(object[] sortArray, CompareOp co)
    {
        for (int i = 0; i < sortArray.Length; i++)	//使用传进来的函数比较,进行定制化的排序
        {
            for (int j = 0; j < i; j++)
            {
                if (co(sortArray[j], sortArray[i]))
                {
                    object temp = sortArray[i];
                    sortArray[i] = sortArray[j];
                    sortArray[j] = temp;
                }
            }
        }
    }
}
    class Employee
    {
        private string name;
        private decimal salary;
        public Employee(string name, decimal salary)
        {
            this.name = name;
            this.salary = salary;
        }
        public override string ToString()
        {
            return string.Format(name + ",{0:C}", salary);
        }
        public static bool Compare(object e1, object e2)
        {
            Employee ee1 = (Employee)e1;
            Employee ee2 = (Employee)e2;
            return (ee1.salary > ee2.salary) ? true : false;
        }
    }
    class Test
    {
        static void Main(string[] args)
        {
            Employee[] employees ={ new Employee("王平", 2000), new Employee("李明", 1970), new Employee("孙丽", 1800), new Employee("付新", 1950), new Employee("林笑", 1900) };
            CompareOp EmployeeCompareOp = new CompareOp(Employee.Compare);
            BubbleSorter.Sort(employees, EmployeeCompareOp);
            for (int i = 0; i < employees.Length; i++)
                Console.WriteLine(employees[i].ToString());
        }
    }
如何委托

委托是面向对象的,是引用类型,对委托的使用要先定义后实例化,才能调用

delegate int SomeDelegate(int nID, string sName);
SomeDelegate d1=new SomeDelegate(wr.InstanceMethod);
d1(5,”aaa”);

委托实例化的实参方法中的参数和返回类型必
须和委托的定义一致
委托实例化中的参数可以是非静态方法,也可
以是静态方法

using System;

class SimpleClass
{
    public class WorkerClass
    {
        public int InstanceMethod(int nID, string sName)
        {
            int retval = 0;
            retval = nID * sName.Length;
            Console.WriteLine("调用InstanceMethod方法");
            return retval;
        }
        static public int StaticMethod(int nID, string sName)
        {
            int retval = 0;
            retval = nID * sName.Length;
            Console.WriteLine("调用StaticMethod方法");
            return retval;
        }
    }
    public delegate int SomeDelegate(int nID, string sName);
    static void Main()
    {
        //调用实例方法
        WorkerClass wr = new WorkerClass();
        SomeDelegate d1 = new SomeDelegate(wr.InstanceMethod);
        Console.WriteLine("Invoking delegate InstanceMethod, return={0}", d1(5, "aaa"));
        //调用静态方法
        SomeDelegate d2 = new SomeDelegate(WorkerClass.StaticMethod);
        Console.WriteLine("Invoking delegate StaticMethod, return={0}", d2(5, "aaa"));
    }
}

可以在类的任何地方定义委托,既可以在一个类的内部定义,也可以在类的外部定义,还可以在命名空间中将委托定义为顶层对象
可以给委托定义添加修饰符public、private和protected委托派生于System.Delegate,在语法上总是带有一个参数构造函数,这个参数就是委托引用的方法,这个方法必须匹配最初定义委托时的签名。

委托与C++函数指针的区别

委托可以指向多个方法
当我们唤起一个搭载了多个方法的delegate,所有方法以其被搭载的顺序被依次唤起
委托搭载的所有方法可以不属于同一个类,但必须具有相同的原型,方法可以是静态的或非静态的

namespace myDelegate 
{ 
    public delegate void SendableDelegate( string s);  
    public class Subscriber 
    { 
        public string name; 
 
        public Subscriber( string name) 
        { 
            this.name = name; 
        } 
 
        public void PutNewsPaperIn( string s) 
        { 
            Console.WriteLine( "{0} 在报箱里收到送来的 {1}" , name, s); 
        } 
 
        public void PutMilkIn( string s) 
        { 
            Console.WriteLine( "{0} 在奶箱里收到送来的 {1}" , name, s); 
        } 
    } 
 
    public class NewsPaperSender 
    { 
        // 委托实现 
        public event SendableDelegate SendNewsPaperHandler; 
 
        public void SendNewsPaper() 
        { 
            if (SendNewsPaperHandler != null) 
                SendNewsPaperHandler( " 报纸 " ); 
        } 
 
        public void Subscribe( SendableDelegate sd) 
        { 
            SendNewsPaperHandler += sd; 
        } 
    } 
 
    public class MilkSender 
    { 
        // 委托实现 
        public event SendableDelegate SendMilkHandler; 
 
        public void SendMilk() 
        { 
            if (SendMilkHandler != null) 
                SendMilkHandler( " 牛奶 " ); 
        } 
 
        public void Subscribe( SendableDelegate sd) 
        { 
            SendMilkHandler += sd; 
        } 
    } 
    // 功能的实现 
    public class Client 
    {         
        public static void Main( string[] args ) 
        { 
            // 委托实现 
            MilkSender ms = new MilkSender(); 
            NewsPaperSender nps = new NewsPaperSender(); 
            Subscriber s1 = new Subscriber( " 张三 " ); 
            Subscriber s2 = new Subscriber( " 李四 " ); 
            Subscriber s3 = new Subscriber( " 王五 " );  
            ms.Subscribe( new SendableDelegate(s1.PutMilkIn)); 
            ms.Subscribe( new SendableDelegate(s2.PutMilkIn)); 
            nps.Subscribe( new SendableDelegate(s2.PutNewsPaperIn)); 
            nps.Subscribe( new SendableDelegate(s3.PutMilkIn)); 
            ms.SendMilk(); 
            nps.SendNewsPaper();         
        } 
    } 
} 

猜你喜欢

转载自blog.csdn.net/le_17_4_6/article/details/86590592