粗看C#委托

  C#的好多定义跟C艹不太相同,先来分析一下“委托”。

1. 委托的定义:

  委托,可以认为是类型安全函数指针,类型安全就是指明确定义了返回类型与参数类型,在C#代码编译时就能够确保指针传参时的安全性。

  值得注意的是,委托也是一种类,在普遍的定义中,“类”表示广泛的定义,泛指一类事物,而对象则表示”类的实例”。但是委托只有一个术语,既表示“类”,也表示”实例”。

  委托类的定义主要是定义它函数指针的返回值、参数类型。委托类的实例化,则是将符合委托类定义的具体函数指针交给一个实例。

 

2. 委托的用法:

  简单的用法不加赘述,把它理解成类型安全的函数指针后就容易多了。

  简单的提示则是:

public delegate string GetString();

int x = 10;

GetString testmethod = new GetString(x.ToString);

  x.ToString 代表的才是函数指针,而不是 x.ToString(),它代表的只是 string 类型的返回值。

 

3. Action<T>与Func<T>:

   在C#代码阅读中,经常发现Action<T>与Func<T>的用法。

Action<T>:这类委托表示引用一个返回类型为void的方法。例如,Action<in T1, in T2> 表示调用带2个参数的方法。

Func<T>:这类委托表示引用一个带返回类型的方法。例如,Func<in T1, out T> 表示带一个参数且有返回类型的方法,out 永远放在最后一位。

 

  使用Action<T>与Func<T>可以一句话就包含了委托类型的定义与实例化:

    class MathOperation
    {
        public static double MultiplyByTwo(double value)
        {
            var res = value * 2;
            Console.WriteLine("MultiplyByTwo:{0}.", res);
            return res;
        }

              public static void ProcessAndDisplay(Func<double, double> action, double value)
        {
            Console.WriteLine();
            Console.WriteLine("ProcessAndDisplay called with value = {0}.", value);
            double res = action(value);
        }  
    }

    class Program
    {
        static void Main(string[] args)
        {
            Func<double, double> MathOperations = MathOperation.MultiplyByTwo;

            MathOperation.ProcessAndDisplay(MathOperations, 2);
            Console.ReadLine();
        }
    }

  Func<double, double> MathOperations = MathOperation.MultiplyByTwo;

  在这里就无需先 delegate double MathOperations(double value) 的声明了。

 

4. 多播委托

    class MathOperation
    {
        public static double MultiplyByTwo(double value)
        {
            var res = value * 2;
            Console.WriteLine("MultiplyByTwo:{0}.", res);
            return res;
        }

        public static double Square(double value)
        {
            var res = value * value;
            Console.WriteLine("Square:{0}.", res);
            return res;

        }

        public static void ProcessAndDisplay(Func<double, double> action, double value)
        {
            Console.WriteLine();
            Console.WriteLine("ProcessAndDisplay called with value = {0}.", value);
            double res = action(value);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Func<double, double> MathOperations = MathOperation.MultiplyByTwo;
            MathOperations += MathOperation.Square;

            MathOperation.ProcessAndDisplay(MathOperations, 2);
            MathOperation.ProcessAndDisplay(MathOperations, 5);
            Console.ReadLine();
        }
    }

  执行结果:

  从结果可以看出,每个委托实例事实上可以包含多个方法,相当于“方法数组”,每次调用委托,都会按顺序将“方法数组”中的每个方法逐个执行过去。

  要注意的是,通过一个委托调用多个方法,只要其中一个方法抛出异常,那么整个委托就会停止了。

  这就是多播委托。

 

posted on 2016-08-09 14:45  青墨淡潋  阅读(200)  评论(0)    收藏  举报