• 委托


    一:介绍

     在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
  • 相关阅读:
    flex+spring3.0+blazds 数据推送整理版
    深入理解java虚拟机学习笔记1.
    一个netty序列化引起的思考。
    万年历
    面试理论题
    EF之Database First
    20120902 09:29 SQL、LINQ、Lambda 三种用法
    内容漂浮在图片上(div漂浮)
    生成订单号
    时间对比
  • 原文地址:https://www.cnblogs.com/xiaoyaodijun/p/6668617.html
Copyright © 2020-2023  润新知