首页 > 代码库 > C# 之 委托

C# 之 委托

委托(delegate)
    委托是一种可以把引用存储为函数的类型。委托也可以看成是一种数据类型,可以用于定义变量,但它是一种特殊的数据类型,它所定义的变量能接受的数值只能是一个函数,更确切的说,委托类型的变量可以接受的数值只能是一个函数,更确切的说,委托的变量可以接受一个函数的地址,类似于C++语言的函数指针。
    委托是对函数的封装,可以当作给方法的特征指定一个名称。
    委托是一种引用方法的类型。一旦为委托分配了方法,委托将与该方法具有完全相同的行为。


委托的声明
    委托的声明非常类似于函数,但不带函数体,且要使用delegate关键字。委托的声明指定了一个返回类型和一个参数列表。
    在定义了委托后,就可以声明该委托类型的变量。接着把这个变量初始化为与委托有相同返回类型和参数列表的函数引用。之后,就可以使用委托变量调用这个函数,就像该变量是一个函数一样。


下面来看一个小例子:

namespace 委托
{
    class Program
    {
        //定义一个委托ProcessDelegate,其返回类型和参数与函数Multiply()和Divide()相匹配
        delegate string  ProcessDelegate(double param1, double param2);


        //定义乘法和出除法的函数
        static string Multiply(double param1, double param2)
        {
            return Convert.ToString(param1 * param2);
        }
        static string Divide(double param1, double param2)
        {
            if (param2!=0)
            {
                return Convert.ToString(param1 / param2);
            }
            else
            {
                return "除数不能为0!";
            }
        }
        static void Main(string[] args)
        {
            ProcessDelegate process;    //使用新的委托类型声明一个变量


            //请求用户由逗号分隔两个数字,并把这些数字仿真两个double变量中
            Console.WriteLine("Enter 2 number separated with a comma:");
            string input = Console.ReadLine();
            int commaPos = input.IndexOf(‘,‘);
            double param1 = Convert.ToDouble(input.Substring(0, commaPos));
            double param2 = Convert.ToDouble(input.Substring(commaPos + 1, input.Length - commaPos - 1));


            //让用户选择操作符
            Console.WriteLine("Enter M to mitiply or D to divide:");
            input = Console.ReadLine();


            //根据用户的选择,初始化process委托变量
            if (input=="M")
            {
                process = new ProcessDelegate(Multiply);
            }
            else
            {
                process = new ProcessDelegate(Divide);
            }


            //把委托变量看作一个函数名
            Console.WriteLine("Result:{0}", process(param1, param2));
            Console.Read();
        }
    }
}
为了说明问题,这里没有验证用户输入的有效性。如果这些是“现实中的”代码,就应花更多时间来确保在局部变量param1和param2中得到有效的值。



通过上面的小例子我们可以知道委托的具体实现步骤:
    1.先声明一个委托实例
    2.提供要处理的方法
    3.实例化委托(把委托看作是类的话,实例化委托就不难理解了,其参数是要处理的方法,这里的方法不用加括号,实例化的过程就是装载方法的过程)实例化后的委托对象就好比是C++中的指针,它本身就是封装了方法的对象
    4.最后我们调用委托对象就好比调用了被封装方法本身,调用时的参数也就传给了被封装的方法