C# 委托的简单介绍

委托 - C# 编程指南 | Microsoft Docs

委托是一种引用类型,表示具有特定参数列表和返回类型的方法的引用。 在实例化委托时,你可以将其实例与任何具有兼容签名和返回类型的方法相关联。 你可以通过委托实例调用方法

 委托用于将方法(该方法可以是静态方法,也可以是实例方法)作为参数传递给其他方法。 事件处理程序就是通过委托调用的方法。

using System;
using System.Collections.Generic;
using System.Linq;

namespace DemoProject_delegate01
{
    class Program
    {
        public delegate string Reverse(string s); //创建特定签名的委托类型,在本例中即接受字符串参数并返回字符串参数的方法。
        static string ReverseString(string s) //方法与定义的委托类型具有完全相同的签名,用于实现委托
        {
            return new string(s.Reverse().ToArray());
        }
        static void Main(string[] args)
        {
            Reverse s = ReverseString;  //可将方法分配给相应委托类型的变量
            Console.WriteLine(s("a string"));


            ///为简化开发过程,.NET 包含一组委托类型,程序员可重用这些类型而无需创建新类型。 
            ///这些类型是 Func<>、Action<> 和 Predicate<>,可以使用它们而无需定义新的委托类型。

            //Func<in T, out TResult> 通常用于现有转换的情况,也就是说需要将委托参数转换为其他结果时
            Func<string, string> s2 = ReverseString;
            Console.WriteLine(s2("string2"));

            //“内联”委托,无需指定任何其他类型或方法
            List<int> list = new List<int>();
            for(int i =1; i<= 10; i++)
            {
                list.Add(i);
            }
            List<int> result = list.FindAll(
                delegate(int no)  //使用匿名方法来声明和初始化委托
                {
                    return (no % 2 == 0);
                }
                );
            foreach(var item in result)
            {
                Console.WriteLine(item); //2,4,6,8,10
            }

            List<int> result2 = list.FindAll(i => i % 2 == 0); //lambda 表达式只是指定委托的另一种方式
            foreach (var item in result) 
            {
                Console.WriteLine(item); //2,4,6,8,10
            }

            Console.ReadKey();

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

namespace DemoProject_delegate01
{
    class Demo03_delegate
    {
        //CLR 公共语言运行库 (common language runtime)环境中给我们内置了几个常用委托Action、 Action<T>、Func<T>、Predicate<T>
        //一般我们要用到委托的时候,尽量不要自己再定义一 个委托了,就用系统内置的这几个已经能够满足大部分的需求,且让代码符合规范。

        //总结:
        //如果要委托的方法没有参数也没有返回值就想到Action
        //有参数但没有返回值就想到Action<T>
        //无参数有返回值、有参数且有返回值就想到Func<T>
        //有bool类型的返回值,多用在比较器的方法,要委托这个方法就想到用Predicate<T>


        //Action封装的方法没有参数也没有返回值,声明原型为:
        //public delegate void Action();

        public delegate void Action();
        public void PrintDemo()
        {
            Console.WriteLine("this is a print method");
        }
        public void ActionDemo()
        {
            //Action a = PrintDemo;
            Action a = new Action(PrintDemo);
            a();

            Action b = () => { Console.WriteLine("this is a print method"); };
            b();

            Action<int,int> c = ShowResult;
            c(1, 2);
            Action<int, int> d = (a, b) => { Console.WriteLine("a={0},b={1},a+b={2}", a, b, a + b); };
            d(1, 2);

            Func<int, int, bool> e = Compare;
            var result1 = e(1, 2);
            Console.WriteLine(result1);

            Func<int,int,bool> f = (a, b) => { return a > b; };
            var result2 = f(1, 2);
            Console.WriteLine(result2);


            Predicate<int> t = new Predicate<int>(Match);   //定义一个比较委托
            int[] arr = { 13, 45, 26, 98, 3, 56, 72, 24 };
            int first = Array.Find(arr, t);                 //找到数组中大于60的第一个元素
            

            Predicate<int> t2 = val => { return val > 60; };
            int first2 = Array.Find(arr, t2);



        }

        //Action<T>是Action的泛型实现,也是没有返回值,但可以传入最多16个参数,两个参数的声明原型为:
        //public delegate void Action<in T1, in T2>(T1 arg1, T2 arg2);
        public delegate void Action<in T1, in T2>(T1 arg1, T2 arg2);  //in(泛型修饰符)
        private void ShowResult(int a,int b)
        {
            Console.WriteLine("a={0},b={1},a+b={2}", a, b, a + b);
        }

        //Func<T>委托始终都会有返回值,返回值的类型是参数中最后一个,可以传入一个参数,也可以最多传入16个参数
        public delegate TResult Func<in T1, in T2, out TResult>(T1 arg1, T2 arg2);

        public bool Compare(int a,int b)
        {
            return a > b;
        }


        //Predicate<T>委托表示定义一组条件并确定指定对象是否符合这些条件的方法,返回值始终为bool类型,声明原型为:
        //public delegate bool Predicate<in T>(T obj); 不需要自己定义

        public bool Match(int val)
        {
            return val > 60;
        }


    }
}

posted @ 2021-09-27 16:43  highlightyys  阅读(9)  评论(0编辑  收藏  举报