C# 委托 简介

委托简介

本文只介绍怎么用,至于在什么情况下用,只能靠经验积累,望各位日后用心感悟哦

  • Delegate使用
  • Action使用
  • Func使用
  • Predicate使用
  • 匿名委托
  • 异步委托(进阶)
温馨提示:相关解释都在每一行代码注释中 ~

Delegate使用

	public delegate void CalculatorDelegate(int a, int b);
    public delegate int CalculatorDelegate1(int a, int b);
    public class maintest
    {
        /// <summary>
        /// Delegate程序入口
        /// </summary>
        /// <param name="action"></param>
        /// <param name="a"></param>
        /// <param name="b"></param>
        public void Run()
        {
            int a = 2;
            int b = 3;
            #region 简单委托
            CalculatorDelegate calculatorDelegate = new CalculatorDelegate(CalculatorAddImple);
            if (calculatorDelegate != default(CalculatorDelegate))
            {
                calculatorDelegate(a, b);
            }
            #endregion
            
            #region 多播委托 
            CalculatorDelegate multiCalculatorDelegate = default(CalculatorDelegate);
            //加法计算器
            multiCalculatorDelegate += new CalculatorDelegate(CalculatorAddImple);
            //加法计算器 + 减法计算器
            multiCalculatorDelegate += new CalculatorDelegate(CalculatorSubImple);
            //加法计算器 + 减法计算器 + 乘法计算器
            multiCalculatorDelegate += new CalculatorDelegate(CalculatorChengImple);
            //加法计算器 + 减法计算器 + 乘法计算器 + 除法计算器
            multiCalculatorDelegate += new CalculatorDelegate(CalculatorChuImple);
            if (multiCalculatorDelegate != default(CalculatorDelegate))
            {
                multiCalculatorDelegate(a, b);
            }
            #endregion

            #region 带返回值类型的委托

            #region 简单委托
            CalculatorDelegate1 calculatorDelegate1 = new CalculatorDelegate1(CalculatorAddImple1);
            if (calculatorDelegate1 != default(CalculatorDelegate1))
            {
                calculatorDelegate1(a, b);
            }
            #endregion

            #region 多播委托
            CalculatorDelegate1 multiCalculatorDelegate1 = default(CalculatorDelegate1);
            //加法计算器
            multiCalculatorDelegate1 += new CalculatorDelegate1(CalculatorAddImple1);
            //加法计算器 + 减法计算器
            multiCalculatorDelegate1 += new CalculatorDelegate1(CalculatorSubImple1);
            //加法计算器 + 减法计算器 + 乘法计算器
            multiCalculatorDelegate1 += new CalculatorDelegate1(CalculatorChengImple1);
            //加法计算器 + 减法计算器 + 乘法计算器 + 除法计算器
            multiCalculatorDelegate1 += new CalculatorDelegate1(CalculatorChuImple1);
            if (multiCalculatorDelegate1 != default(CalculatorDelegate1))
            {
                //委托有返回值,就会只返回最后一个实现方法的返回值
                var yy = multiCalculatorDelegate1(a, b);
                //只要委托不等于空,反复删除同一个委托,不会报错并且不会执行
                multiCalculatorDelegate1 -= new CalculatorDelegate1(CalculatorSubImple1);
                multiCalculatorDelegate1 -= new CalculatorDelegate1(CalculatorSubImple1);
                var yy2 = multiCalculatorDelegate1(a, b);
                //委托清空,才会报错
                multiCalculatorDelegate1 -= new CalculatorDelegate1(CalculatorSubImple1);
                multiCalculatorDelegate1 -= new CalculatorDelegate1(CalculatorAddImple1);
                multiCalculatorDelegate1 -= new CalculatorDelegate1(CalculatorChengImple1);
                multiCalculatorDelegate1 -= new CalculatorDelegate1(CalculatorChuImple1);
                var yy3 = multiCalculatorDelegate1(a, b);
            }
            #endregion
            #endregion
            
		    #region dynamicinvoke
            //动态传入参数: 
            //编译时:参数数量不匹配,参数类型不匹配,参数顺序不一致,都不会报错,但是运行时会报错
            CalculatorDelegate1 dynamicDelegate = new CalculatorDelegate1(CalculatorAddImple1);
            dynamicDelegate.DynamicInvoke(a, b);
            #endregion
        }

        public void CalculatorAddImple(int a, int b)
        {
            Console.WriteLine("加法:" + (a + b));
        }

        public void CalculatorSubImple(int a, int b)
        {
            Console.WriteLine("减法:" + (a - b));
        }

        public void CalculatorChengImple(int a, int b)
        {
            Console.WriteLine("乘法:" + (a * b));
        }

        public void CalculatorChuImple(int a, int b)
        {
            Console.WriteLine("除法(整除):" + (a / b));
        }

        public int CalculatorAddImple1(int a, int b)
        {
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
            for (int i=0;i<10000;i++)
            {
                for (int j = 0; j < 100000; j++)
                {
                    Console.WriteLine("CalculatorAddImple1 method working");
                }
            }
            stopwatch.Stop();
            Console.WriteLine($"waste time:{stopwatch.ElapsedMilliseconds}");
            Console.WriteLine("加法:" + (a + b));
            return 1;
        }

        public int CalculatorSubImple1(int a, int b)
        {
            Console.WriteLine("减法:" + (a - b));
            return 1;
        }

        public int CalculatorChengImple1(int a, int b)
        {
            Console.WriteLine("乘法:" + (a * b));
            return 1;
        }

        public int CalculatorChuImple1(int a, int b)
        {
            Console.WriteLine("除法(整除):" + (a / b));
            return 4;
        }
    }

Action使用

该委托没有返回类型

		public void ActionTestImple(int a)
        {
            Console.WriteLine("Action 委托实现方法");
        }

        /// <summary>
        ///  Action委托测试入口
        /// </summary>
        /// <returns></returns>
        public void ActionTest()
        {
            Action<int> action = new Action<int>(ActionTestImple);
            //该委托没有返回类型
            action(1);
        }

Func使用

有返回值的委托

		public bool FuncTestImple(int a)
        {
            return false;
        }

        /// <summary>
        /// Func委托测试入口
        /// Func<int, bool> -  int:参数   bool:返回值
        /// Func<int>  - int:返回值
        /// </summary>
        /// <param name="calculatorAction"></param>
        public void FuncTest(CalculatorDelegate calculatorAction)
        {
            var array = new int[5] { 1, 5, 9, 4, 6 };
            //有返回值的函数运用
            Func<int, bool> predicateNormal = new Func<int, bool>(FuncTestImple);
            array.FirstOrDefault(predicateNormal);
        }

Predicate使用

该委托只返回bool类型

    /// <summary>
    /// Predicate委托测试入口
    /// </summary>
    /// <returns></returns>
    public void PredicateTest()
    {
        Predicate<int> predicate = new Predicate<int>(PredicateTestImple);
        //该委托只返回bool类型
        bool flag=predicate(1);
    }

匿名委托

		public bool FuncTestImple(int a)
        {
            return false;
        }

        /// <summary>
        /// 匿名委托测试入口
        /// Func<int, bool> -  int:参数   bool:返回值
        /// Func<int>  - int:返回值
        /// </summary>
        /// <param name="calculatorAction"></param>
        public void FuncTest(CalculatorDelegate calculatorAction)
        {
            var array = new int[5] { 1, 5, 9, 4, 6 };
           

            //有返回值的函数运用
            Func<int, bool> predicateNormal = new Func<int, bool>(FuncTestImple);
            array.FirstOrDefault(predicateNormal);

            //有返回值的匿名函数运用
            //  ----------------方法1
            Func<int, bool> predicate = delegate (int sth)
              {
                  return false;
              };

            Func<int, bool> predicate1 = (int sth)=>
            {
                return false;
            };

            Func<int, bool> predicate2 = (it) =>
            {
                return false;
            };
            array.FirstOrDefault(predicate);
            array.FirstOrDefault(predicate1);
            array.FirstOrDefault(predicate2);
            //  ----------------方法2
            array.FirstOrDefault(delegate (int sth)
            {
                return false;
            });
            array.FirstOrDefault( (int sth)=>
            {
                return false;
            });
            array.FirstOrDefault((it) =>
            {
                return false;
            });
        }

委托进阶-异步委托

有两种方式供选择:
方式1:
可以结合业务决定什么时候主动调用EndInvoke获取结果

  		/// <summary>
        /// 程序入口
        /// </summary>
        /// <param name="action"></param>
        /// <param name="a"></param>
        /// <param name="b"></param>
        public void Run()
        {
            int a = 2;
            int b = 3;

            #region 委托进阶-异步委托
            CalculatorDelegate1 myDelegate = new CalculatorDelegate1(CalculatorAddImple1);
            IAsyncResult asyncResult = myDelegate.BeginInvoke(a, b, null, null);
            //调用EndInvoke,当前线程会等待结果生成,不会执行之后的代码,所以自己决定什么时候调用该方法。
            var value = myDelegate.EndInvoke(asyncResult);
         }   

		/// <summary>
        /// 回调函数,当该异步实现方法执行完毕之后,由该方法进行EndInvoke取结果并结束该线程。
        /// </summary>
        /// <typeparam name="TInput"></typeparam>
        /// <param name="asyncResult"></param>
        private void Completed<TInput>(IAsyncResult asyncResult) where TInput : Point
        {
            AsyncResult result = (AsyncResult)asyncResult;
            //beginInvoke 取最后一个参数
            var param = result.AsyncState as Point;
            //取beginInvoke的delegate对象
            var myDelegate = result.AsyncDelegate as CalculatorDelegate1;
            //取Invoke的最终结果
            var value=myDelegate.EndInvoke(asyncResult);
        }

方式2(推荐):
在进程结束之前,如果还有异步结果没有完成,让当前进程等待其全部完成,调用如下:GlobalAsyncResultCache.WaitAllFinished();

		/// <summary>
        /// 程序入口
        /// </summary>
        /// <param name="action"></param>
        /// <param name="a"></param>
        /// <param name="b"></param>
        public void Run()
        {
            int a = 2;
            int b = 3;

            #region 委托进阶-异步委托
            CalculatorDelegate1 myDelegate = new CalculatorDelegate1(CalculatorAddImple1);
            IAsyncResult asyncResult = myDelegate.BeginInvoke(a, b, Completed<Point>, new Point() { x = 1, y = 1 });
            GlobalAsyncResultCache.AddRuningResult(asyncResult);
         }   

		/// <summary>
        /// 回调函数,当该异步实现方法执行完毕之后,由该方法进行EndInvoke取结果并结束该线程。
        /// </summary>
        /// <typeparam name="TInput"></typeparam>
        /// <param name="asyncResult"></param>
        private void Completed<TInput>(IAsyncResult asyncResult) where TInput : Point
        {
            AsyncResult result = (AsyncResult)asyncResult;
            //beginInvoke 取最后一个参数
            var param = result.AsyncState as Point;
            //取beginInvoke的delegate对象
            var myDelegate = result.AsyncDelegate as CalculatorDelegate1;
            //取Invoke的最终结果
            var value=myDelegate.EndInvoke(asyncResult);
        }
        /// <summary>
    	/// 进程内异步结果缓存
   		/// </summary>
   	    public class GlobalAsyncResultCache
    	{
    	
		    private static IList<IAsyncResult> asyncResults = new List<IAsyncResult>();
	        public static void AddRuningResult(IAsyncResult result)
	        {
	            asyncResults.Add(result);
	        }
	
	        public static void WaitAllFinished()
	        {
	            foreach (IAsyncResult asyncResult in asyncResults)
	            {
	                WaitOne(asyncResult);
	            }
	        }
	
	        private static void WaitOne(IAsyncResult asyncResult)
	        {
	            while (!asyncResult.IsCompleted)
	            {
	                System.Threading.Thread.Sleep(1);
	            }
	        }
    	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值