委托(非常详细)

委托

C# 中的委托(Delegate)类似于 C 或 C++ 中函数的指针。委托(Delegate) 是存有对某个方法的引用的一种引用类型变量。引用可在运行时被改变。(可以理解为是一种数据类型。)

委托(Delegate)用于实现事件和回调方法。所有的委托(Delegate)都派生自 System.Delegate 类。

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

//声明一个委托,委托的声明只是声明了一个方法的类型
//格式:访问修饰符 delegate 方法的返回值类型 委托的名称(方法的参数....)
public delegate  bool MyDelegate(string v);
namespace _04_委托
{
    internal class Program
    {
        static void Main(string[] args)
        {
            //C#是强类型的编程语言,强类型编程语言的特性是所有的东西都有特定的类型
            //变量,属性 ,字段...在定义的时候都需要显式的指定他们的类型
            //方法,之前没有类型,委托其实就是一个类型,我们可以使用委托创建一个方法的类型
            Test.TestFn(MyFn);
        }
        static bool MyFn(string a)
        {
            Console.WriteLine("这是个函数"+a);
            return true;
        }
    }

    class Test
    {
        //方法接收一个委托类型的参数,就相当于接收一个方法,该方法必须满足这个委托规定的参数和返回值
        public static void  TestFn(MyDelegate f) {

            f("吴亦凡");
        
        }
    }
}

委托的实例化

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

//1.创建一个委托类型,只能保存没有返回值并且参数为 int和string类型的方法
delegate void MyFns(int v1,string v2);
delegate int NumberOperator(int v1, int v2);
namespace _05_委托的实例化
{
    internal class Program
    {
        static void Main(string[] args)
        {
            new TestClass();
        }
      
    }

    class TestClass
    {
        public TestClass()
        {
            int a = 1;
          
            //2.实例化一个委托的时候必须传递一个方法
            MyFns fns1=new MyFns(Fn1);

            Fn1(1, "wuyifan");

            //委托类型的变量,可以将它理解为一个特殊的方法,直接将他当做方法调用即可
            fns1(1,"luozhxinag");

            //练习: 定义一个委托,接收两个int参数,返回int类型参数,并且创建一个委托类型的变量并调用该委托


            NumberOperator no = new NumberOperator(Add);

            int num1=  Add(10,30);
            Console.WriteLine(num1);
            int num2=    no(6,8);
            Console.WriteLine(num2);



            // NumberOperator no2 = new NumberOperator(Cheng
            // 委托创建可以简写

            NumberOperator no2 = Cheng;
            Console.WriteLine(no2(2,4));


            //委托的另外一个调用方法
            int v=  no2.Invoke(2, 4);
            Console.WriteLine(v);

        }


        void Fn1(int a, string b)
        {
            Console.WriteLine($"a={a},b={b}");
        }
        int Add(int a, int b)
        {
            return a + b;
        }
        int Cheng(int a, int b)
        {
            return a * b;
        }
    }

}

多播委托

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

delegate void MyDelegate(string name);
namespace _06_多播委托
{
    internal class Program
    {
        static void Main(string[] args)
        {
            //包含多个方法的委托,称之为多播委托

            MyDelegate fns = new MyDelegate(Fn1);

            //使用+=运算符,在委托变量上添加一个方法
            fns += new MyDelegate(new Test().Fn2);
            //如果这个委托类型的变量,存储了多个方法,当该委托被调用的时候,将会执行所有的方法并传递参数
            fns("吴亦凡");

            //简写
            MyDelegate fns2 = Fn1;
            fns2 += new Test().Fn2;

            fns2("luozhixinag");

            MyDelegate fns3 = Fn1;
            fns3 += new Test().Fn2;
            //还可以使用-=从委托中移除一个方法
            fns3 -= Fn1;
            fns3("李云迪");



            Console.WriteLine("---------------------------");
            MyDelegate fns4 = Fn1;
            fns4 += new Test().Fn2;
            fns4 -= new Test().Fn2;
            // 这个委托同样会被调用两次, 因为39行和40行操作的不是同一个方法
            //fns4("郑爽");
            fns4.Invoke("郑爽");

            //一下这些代码 等价于 以上代码
            MyDelegate fns5 = Fn1;
            Test t1=new Test();
            Test t2=new Test();
            fns5 += t1.Fn2;
            fns5 -= t2.Fn2;
            fns5.Invoke("郑爽");
            Console.WriteLine("-----------------------------");

            //解决方案1:将对象使用变量保存, 执行+=和-=操作
            MyDelegate fns6 = Fn1;
            Test t=new Test();
            fns6 += t.Fn2;
            fns6 -= t.Fn2;
            fns6.Invoke("郑爽2.0");


            //
            MyDelegate fns7 = Fn1;
            fns7 += Test.Fn3;
            fns7 -= Test.Fn3;

            fns7.Invoke("曹云金");
        }
        public static void Fn1(string v)
        {
            Console.WriteLine($"这是Fn1中的v:{v}");
        }
    }
    class Test
    {
        public void Fn2(string v)
        {
            Console.WriteLine($"这是Fn2中的v:{v}");
        }

        public static void Fn3(string v)
        {
            Console.WriteLine($"这是Fn3中的v:{v}");
        }
    }
}

委托的调用

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

namespace _07_委托的调用
{
    internal class Program
    {
        static void Main(string[] args)
        {
              Test t=new Test();

              t.Run();
        }
    }

    class Test
    {
        public delegate int MyDealegate(int x);
        public MyDealegate Fns {get;set; }


        public Test()
        {
            Fns += Fn1;
            Fns += Fn2;
        }


        public int Fn1(int v)
        {
            Console.WriteLine(v*10);
            return v*10;
        }
        public int Fn2(int v)
        {
            Console.WriteLine(v * v);
            return v * v;
        }

        People p;
        public void Run()
        {
            //1.委托被调用的时候,会执行该委托变量中存储的所有的方法
            //Fns(888);
            //2.当委托中没有存储任何方法的时候,执行会报错:未将对象引用设置到对象的实例
            // if (Fns != null)  Fns(7); 

            //简写为 ?. 运算符  当前面的值为null的时候 不往后执行
            Fns?.Invoke(7);



            //?. 用于从可能为空的值上获取他的属性, 即使该值为null 也不会报错
            Console.WriteLine(p?.Name==null);
            p=new People();
            p.Name = "罗志祥";
            Console.WriteLine(p?.Name);
        }



    }
    class People
    {
        public string Name;
    }

}

内置委托类型

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

//delegate void FnDelegate1();
//delegate void FnDelegate2(int v, string s);
//delegate void FnDelegate3(int v1,int v2);
namespace _08_内置委托类型
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Test.Fn1(f1);
            Test.Fn2(f2);
            Test.Fn3(f3);
            Test.Fn4(f4);
            Test.Fn5(f5);
            //这种形式的创建委托比较麻烦,如果该委托只用一次,当做方法的参数的时候,就显得代码比较臃肿,
            //c#内置了一些委托, 通过泛型指定他的参数类型

            //Action  Func

        }
        static void f1() { }
        static void f2(int i,string s) { }
        static void f3(int[] i1, bool[] b2) { }
        static string f4() { return "123"; }
        static string f5(int i) { return "123"; }
    }
    class Test
    {
        //一个不接收参数,没有返回值
        //Action 用于指定一些不拥有返回值的委托
        public static void Fn1(Action fn)
        {

        }
        //一个接收 int string类型的参数,没有返回值
        public static void Fn2(Action<int,string> fn)
        {

        }
        //一个接收 int[] bool[]  没有返回值
        public static void Fn3(Action<int[], bool[]> fn)
        {

        }

        //一个不接收参数 返回string 
        //Func 用于指定一些用于返回值的委托
        public static void Fn4(Func<string> fn)
        {

        }
        //接收int  返回string 
        public static void Fn5(Func<int,string>fn)
        {

        }
        //接收int 返回 int 
        public static void Fn6(Func<double,int> fn)
        {

        }
    }
}

委托练习

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

namespace _09_委托练习
{
    internal class Program
    {
        static void Main(string[] args)
        {
            int[] ints = new int[] { 1, 2, 43, 5, 56, 6, 7 };
            //int num1= Array.Find(ints,Fn2);

            int num2 = FindFrist(ints, Fn2);
            Console.WriteLine(num2);
            //自定义Find
        }


        public static bool Fn2(int value)
        {
            return value % 2 == 0;
        }
        public  static int FindFrist(int[] ints,Func<int,bool> fn)
        {

            for (int i = 0; i < ints.Length; i++)
            {
                if (fn(ints[i])==true)
                {
                    return ints[i];
                }
            }
            return 0;
        }

    }

}

泛型委托

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

delegate bool CAllBack<T>(T s);
namespace _10_泛型委托
{
    internal class Program
    {
        static void Main(string[] args)
        {
           string[] strings = { "亦凡1", "吴亦凡2", "罗志祥" };

            string s = FindFirst<string>(strings, FindWu);

            int[] ints = { 1, 3, 5, 6, 5 };

           // int i=FindFirst<int>(ints, FindEven);
            int i = FindFirst<int>(ints, FindEven);

            Console.WriteLine(i);

        }
        static bool FindWu(string name)
        {
            return name.StartsWith("吴");
        }
        static bool FindEven(int value)
        {
            return value%2 == 0;
        }

        //public static string FindFirst(string[] Arrs, CAllBack fn)
        //{
        //    for (int i = 0; i < Arrs.Length; i++)
        //    {
        //        if (fn(Arrs[i])==true)
        //        {
        //            return Arrs[i];
        //        }
        //    }
        //    return null;
        //}
        //public static T FindFirst<T>(T[] Arrs, CAllBack<T> fn)
        //{
        //    for (int i = 0; i < Arrs.Length; i++)
        //    {
        //        if (fn(Arrs[i]) == true)
        //        {
        //            return Arrs[i];
        //        }
        //    }
        //    //返回当前类型的默认值
        //    return default(T);
        //}
        public static T FindFirst<T>(T[] Arrs, Func<T,bool> fn)
        {
            for (int i = 0; i < Arrs.Length; i++)
            {
                if (fn(Arrs[i]) == true)
                {
                    return Arrs[i];
                }
            }
            //返回当前类型的默认值
            return default(T);
        }
    }
}

Lambda表达式(进阶)

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

namespace _11_Lambda表达式_进阶_
{
    internal class Program
    {
        static void Main(string[] args)
        {
            int Add(int x,int y)
            {
                return x + y;
            }
            //Lambda表达式 用于创建一个函数
            Console.WriteLine(Add(1,2));

            Action<int, string> fn1 = (int argOne, string argTwo) =>
            {
                Console.WriteLine(argOne + argTwo);
            };

            fn1(1,"吴亦凡");

            //格式:Func<参数1的类型,参数2的类型,返回值类型>fnName(参数1,参数2)=>{函数的内容}
            Func<int, int, bool> fnName1 = (int a, int b) =>
            {
                return a > b;
            };
            //调用的时候和普通的函数相同
            Console.WriteLine(fnName1(19, 10));

            //lambda表达式的声明可以简化

            //1.函数的实现中,参数的类型可以省略
            Func<int, int, bool> fnName2 = (a, b) =>
            {
                return a > b;
            };

            //2.如果只有一个参数,可以省略()
            Func<int, bool> fnName3 = a =>
            {
                return a % 2 == 0;
            };

            //3.如果函数中只有一个表达式,,可以省略{}和return,他会自动返回表达式的运行结果
            Func<int, bool> fnName4 = a => a % 2 == 0;

            //如下代码和53代码等价
            Func<int, int, bool> fnName5 = (a, b) => a > b;


            int[] ints = new int[] { 3, 4, 5, 6 };
            FindFirst(ints, FindEven);
            FindFirst(ints,  v =>  v % 2 == 0);

        }
        static bool FindEven(int value)
        {
            return value % 2 == 0;
        }


        public static T FindFirst<T>(T[] Arrs, Func<T, bool> fn)
        {
            for (int i = 0; i < Arrs.Length; i++)
            {
                if (fn(Arrs[i]) == true)
                {
                    return Arrs[i];
                }
            }
            //返回当前类型的默认值
            return default(T);
        }

    }
}


   

   


相关推荐

  1. 委托(非常详细)

    2024-03-25 19:08:08       19 阅读
  2. 【.NET Core】委托(Delegate)应用详解

    2024-03-25 19:08:08       21 阅读
  3. 【C#语言入门】16. 委托详解

    2024-03-25 19:08:08       19 阅读
  4. Mysql知识详解(内容非常丰富)

    2024-03-25 19:08:08       31 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-03-25 19:08:08       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-25 19:08:08       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-25 19:08:08       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-25 19:08:08       20 阅读

热门阅读

  1. [leetcode] 994. 腐烂的橘子

    2024-03-25 19:08:08       18 阅读
  2. 爬取MalwareBazaar实现恶意样本数据自由

    2024-03-25 19:08:08       24 阅读
  3. C++多态

    C++多态

    2024-03-25 19:08:08      24 阅读
  4. Python从入门到精通秘籍十九

    2024-03-25 19:08:08       26 阅读
  5. 【软考】蠕虫病毒

    2024-03-25 19:08:08       27 阅读
  6. 用Python做一个植物大战僵尸

    2024-03-25 19:08:08       20 阅读
  7. 工作中常用的git命令

    2024-03-25 19:08:08       16 阅读
  8. 在树莓派4B上安装Ubuntu Server 20

    2024-03-25 19:08:08       19 阅读