委托

一:介绍

 在C#中,委托是一种类型,属于引用类型,委托的关键字是delegate,委托的定义和类的定义一样,所以凡是能定义类的地方也是可以定义委托的。委托是一种可用于封装命名或匿名方法的引用类型。 委托类似于 C++ 中的函数指针;但是,委托是类型安全和可靠的

二:声明委托


//声明一个无参数无返回值的委托
public delegate void DelegateMethod();

//声明一个有一个参数,无返回值的委托
//public delegate void DelegateMethod(string str);
//声明一个无参数,有返回值的委托
//public delegate string DelegateMethod();
//声明一个有一个参数,有返回值的委托
//public delegate string DelegateMethod(string str);

//声明一个DelegateMethod 类型的对象,DelegateMethod 是类型,DelegateOption是对象
public DelegateMethod DelegateOption;

三:栗子

        public delegate void DelegateMethod(string str);
        
        public void Use()
        {
            DelegateMethod dm = new DelegateMethod(TestUse);
            dm("小明");
        }

        public void TestUse(string name)
        {
            Console.WriteLine("委托测试-"+name);
        }

四:部分源码

 public abstract class Delegate : ICloneable, ISerializable
     {
       [ForceTokenStabilization, SecurityCritical]
          internal object _target;
          [SecurityCritical]
          internal object _methodBase;
          [ForceTokenStabilization, SecurityCritical]
          internal IntPtr _methodPtr;
         [ForceTokenStabilization, SecurityCritical]
         internal IntPtr _methodPtrAux;
}

_methodPtr 是指向该方法的指针.

_methodBase 是给委托赋值时传递的方法

 五:泛型委托,Action和Func

①Action给我们提供的是只有参数而不带返回值的委托,

②Func给我们提供的是有参数有返回值的委托,Result表示返回值

action应用

        public void Use()
        {
            Action<string> ac = TestUse;
            ac("小明");
        }

        public void TestUse(string name)
        {
            Console.WriteLine("委托测试-"+name);
        }
func应用
        public void Use()
        {
            Func<string, string> fc = TestUse;
            var result = fc("大名");
            Console.WriteLine(result);
        }

        public string TestUse(string name)
        {
            return "测试" + name;      
        }

泛型委托的好处

第一 : 可以减少我们委托的定义数量

第二 : 泛型是类型安全的

第三 : 方便进行协变和逆变

第四 : 简化代码

五:多播委托,委托链

    public class DelegateUse
    {
        public delegate void DelegateMethod();

        public DelegateMethod DelegateOption;

        public void TestUse()
        {

            Console.WriteLine("委托测试");
        }

        public void GetTest()
        {

            Console.WriteLine("无参数委托");
        }

        public void Test()
        {
            Console.WriteLine("无参数无返回值委托");
        }

        public void RunDelegate()
        {
            DelegateOption.Invoke();
        }

    }
            DelegateUse du = new DelegateUse();
            du.DelegateOption = new DelegateUse.DelegateMethod(du.Test);
            du.DelegateOption += new DelegateUse.DelegateMethod(du.TestUse);
            du.DelegateOption += new DelegateUse.DelegateMethod(du.GetTest);
            du.RunDelegate();

如果把"+"换成等于号,则只能显示最后一个委托的数据,前面的都被覆盖了

 六:委托的异步调用

①委托对象有void Invoke , System.IAsyncResult BeginInvoke,void EndInvoke . 这三个构造函数
②EndInvoke 方法检索异步调用的结果。 在调用 BeginInvoke 之后随时可以调用该方法。 如果异步调用尚未完成,则 EndInvoke 会一直阻止调用线程,直到异步调用完成
Invoke : 委托回调函数时候的一种同步调用方式.
BeginInvoke : 委托回调函数时候的一种异步调用方式.和Invoke对立
EndInvoke : 异步调用,用于检索调用结果.
        public delegate void DelegateMethod(string str);

        public void Use()
        {
            DelegateMethod dd = GetTest;     
            var k = dd.BeginInvoke("canshu", null, null);
            dd.Invoke("参数");
            dd.EndInvoke(k);
            Console.WriteLine();
        }

        public void GetTest(string name)
        {
            Console.WriteLine("无参数委托----" + name);
        }

结果:

无参数委托----参数
无参数委托----canshu

 

posted @ 2017-04-05 14:34  逍遥帝君  阅读(191)  评论(0编辑  收藏  举报