一:什么是委托

      委托是一种定义方法签名的类型当实例化委托时,您可以将其实例与任何具有兼容签名的方法相关联。您可以通过委托实例调用方法。委托是一个引用类型,所以它具有引用类型所具有的通性。它保存的不是实际值,而是保存对存储在托管堆(managed heap)中的对象的引用。 委托可以引用静态方法和非静态方法。

         通俗的理解是,委托其实可以是一种简单的约束,好比在工作上我声明了一个委托人A, A同时可以接受(人力资源,后勤公务)两个参数,那么只要是有人想处理(人力资源,后勤)方面的事情,都可以去注册到委托人A上,A有能力接受这些方法,然后去处理。

     二:委托的声明

         声明委托可以通过delegate来声明,委托可以依赖于一个类,也可以依赖于一个namespace间。即 在类里面声明和在类外面声明。其中delegate可以有返回类型和非返回类型,其中delegate也支持泛型。

public delegate double AddNum(double num1,double num2);
public delegate void ShowMsg(string str);

  三: 委托的使用

     1. 基本使用:下面是一个计算方法,声明了一个委托CalculatorDelegate,然后在Main方法里面先后注册了AddNum,和SumNum方法,注册的方法必须与委托的参数以及返回类型相符合,否者将会提示【委托与注册方法不匹配的提示】对于这块是直接编译无法通过的。委托如果被注册了多个方法,称为多播。对于多播,调用委托后,按照注册顺序执行。不过对于有返回值的方法,将返回最后注册的方法执行后的返回值。

         Notes:第一次注册方法的时候可以使用【=注册】或者【new CalculatorDelegate(方法名) 】,后面添加方法用【+】,取消注册方法用【-】

运行代码和运行结果如下图:   

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

namespace SpongeBobCoder.Delegate
{
    public delegate double CalculatorDelegate(double num1, double num2); // 委托,声明在类之外

    public class Program
    {
        public static double AddNum(double num1, double num2)
        {
            Console.WriteLine("Sum={0}", num1 + num2);
            return num1 + num2;
        }

        public static double SubNum(double num1, double num2)
        {
            Console.WriteLine("Sub={0}", num1 - num2);
            return num1 - num2;
        }

        public static void Main(string[] args)
        {
            CalculatorDelegate calculatorDel = AddNum; // 目前为单播
            Console.WriteLine("委托一个方法的结果为:{0}", calculatorDel(1, 2));
            calculatorDel += SubNum; // 目前是多播
            Console.WriteLine("委托两个方法的结果为:{0}", calculatorDel(1, 2));
            Console.ReadKey();
        }
    }
}

    2. 委托注册方法的几种形式:除了上面的方式,其实委托的注册方法还支持Linq方法,匿名方法。其实在Linq中也大量的委托,比如在使用List<T>.where(),List<T>.sort()这些方法的时候其实里面就运用的大量的委托。其实可以理解为就是委托的缩影。

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

namespace SpongeBobCoder.Delegate
{
    public delegate double CalculatorDelegate(double num1, double num2); // 委托

    public class Program
    {
        public static void Main(string[] args)
        {
            CalculatorDelegate calculatorDel = delegate(double x, double y) //等效于AddNum方法
            {
                return x + y;
            };
            Console.WriteLine("委托一个方法的结果为:{0}", calculatorDel(1, 2));

            calculatorDel += (x, y) => // 等效于SumNum方法
            {
                return x - y;
            };

            Console.WriteLine("委托两个方法的结果为:{0}", calculatorDel(1, 2));
            Console.ReadKey();
        }
    }
}

     3. 小添加: 其实在.net框架提供了自带的委托. Action<T>,Func<T,out Result>。Action是无返回值泛型委托,Func是有返回值的泛型委托【out Result就是返回值,不过使用的时候不是要传入一个out参数,对于Action<T,T,out Result>,其实就是传入2个参数。】代码如下:

          Notes:注意Func<>三个参数,可是AddNum只有两个,其实第三个就是对应的返回值,这里有别于我们前面说的委托,希望大家注意.

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

namespace SpongeBobCoder.Delegate
{
    public class Program
    {
        private static void ShowMsg(string str)
        {
            Console.WriteLine(str);
        }

        private static double AddNum(double num1, double num2)
        {
            return num1 + num2;
        }

        public static void Main(string[] args)
        {
            Action<string> action = ShowMsg;
            action("Action委托好用!");
            Func<double, double, double> func = AddNum; // Notes
            Console.WriteLine("Func委托真好用,两数之和为:{0}", func(1, 2));
            Console.ReadKey();
        }
    }
}

 

       四:总结

           因为最近在接触Silverlight,事件委托以后会不断接触。所以这两天看了一下事件委托的知识,并写博客记录一下。有什么理解不对,描述不对的还请各位博友指点指点。下篇会更新事件的使用。

   

posted on 2014-11-02 20:58  FrankZC  阅读(6639)  评论(6编辑  收藏  举报