委托应用及泛型委托和多播委托

【我是谁】 【我是谁】     2022-10-03     171

关键词:

一、委托一般作为方法的参数或者返回值,或者使用多播委托(注册多个方法,可以全部触发)

 

1.示例:根据对于字符串不同的处理方法逻辑
      private delegate void PrintString(string str);

        static void PrintStr( PrintString print,string str )
        {
            print(str);
        }

        static void Method1(string str) {
            Console.WriteLine(str);
        }
        static void Method2(string str)
        {
            Debug.WriteLine(str);
        }
 static void Main(string[] args)
{

           PrintString method = Method1;
            PrintStr(method,"Test");
            method = Method2;
            PrintStr(method,"Test");
            Console.ReadKey();

}

 

二、泛型委托

Action-Action<T>

   class Program {
        static void PrintString()
        {
            Console.WriteLine("hello world.");
        }

        static void PrintInt(int i)
        {
            Console.WriteLine(i);
        }

        static void PrintString(string str)
        {
            Console.WriteLine(str);
        }

        static void PrintDoubleInt(int i1, int i2)
        {
            Console.WriteLine(i1+i2);
        }
        static void Main(string[] args)
        {
            //Action a = PrintString;//action是系统内置(预定义)的一个委托类型,它可以指向一个没有返回值,没有参数的方法
            //Action<int> a=PrintInt;//定义了一个委托类型,这个类型可以指向一个没有返回值,有一个int参数的方法
            //Action<string> a = PrintString;//定义了一个委托类型,这个类型可以指向一个没有返回值,有一个string参数的方法 在这里系统会自动寻找匹配的方法
            Action<int, int> a = PrintDoubleInt;
            a(34, 23);
            Console.ReadKey();
            //action可以后面通过泛型去指定action指向的方法的多个参数的类型 ,参数的类型跟action后面声明的委托类型是对应着的
           
        }
    }

Func<T>  

  class Program {
        static int Test1()
        {
            return 1;
        }

        static int Test2(string str)
        {
            Console.WriteLine(str);
            return 100;
        }

        static int Test3(int i, int j)
        {
            return i + j;
        }
        static void Main(string[] args)
        {
            //Func<int> a = Test1;//func中的泛型类型制定的是 方法的返回值类型
            //Console.WriteLine(a());
            //Func<string, int> a = Test2;//func后面可以跟很多类型,最后一个类型是返回值类型,前面的类型是参数类型,参数类型必须跟指向的方法的参数类型按照顺序对应
            Func<int, int, int> a = Test3;//func后面必须指定一个返回值类型,参数类型可以有0-16个,先写参数类型,最后一个是返回值类型
            int res = a(1, 5);
            Console.WriteLine(res);
            Console.ReadKey();
        }
    }

泛型委托应用:冒泡排序扩展

class Employee {
        public string Name { get; private set; }
        public int Salary { get; private set; }

        public Employee(string name, int salary)
        {
            this.Name = name;
            this.Salary = salary;
        }
        //如果e1大于e2的话,返回true,否则返回false
        public static bool Compare(Employee e1, Employee e2)
        {
            if (e1.Salary > e2.Salary) return true;
            return false;
        }

        public override string ToString()
        {
            return Name + ":" + Salary;
        }
    }
View Code
   class Program {
        static void Sort(int[] sortArray)
        {
            bool swapped = true;
            do
            {
                swapped = false;
                for (int i = 0; i < sortArray.Length - 1; i++)
                {
                    if (sortArray[i] > sortArray[i + 1])
                    {
                        int temp = sortArray[i];
                        sortArray[i] = sortArray[i + 1];
                        sortArray[i + 1] = temp;
                        swapped = true;
                    }
                }
            } while (swapped);
        }

        static void CommonSort<T>(T[] sortArray, Func<T,T,bool>  compareMethod)
        {
            bool swapped = true;
            do {
                swapped = false;
                for (int i = 0; i < sortArray.Length - 1; i++) {
                    if (compareMethod(sortArray[i],sortArray[i+1])) {
                        T temp = sortArray[i];
                        sortArray[i] = sortArray[i + 1];
                        sortArray[i + 1] = temp;
                        swapped = true;
                    }
                }
            } while (swapped);
        }
        static void Main(string[] args) {
            //int[] sortArray = new int[]{123,23,12,3,345,43,53,4};
            //Sort(sortArray);
            //foreach (var temp in sortArray)
            //{
            //    Console.Write(temp+" ");
            //}
            Employee[] employees = new Employee[]
            {
                new Employee("dsf",12), 
                new Employee("435dsf",234), 
                new Employee("234dsf",14), 
                new Employee("ds234f",234), 
                new Employee("dssfdf",90)
            };
            CommonSort<Employee>(employees,Employee.Compare);
            foreach (Employee em in employees)
            {
                Console.WriteLine(em);
            }
            Console.ReadKey();
        }
    }
View Code

多播委托:(可以注册多个方法给委托,也可以注销已注册的方法)

方法:

     static void T1()
        {
            Console.WriteLine("ok");
        }
        static void T2()
        {
            Console.WriteLine("ook");
        }
        static void T3()
        {
            Console.WriteLine("oook");
        }
        static void M1(string msg)
        {
            Console.WriteLine(msg);
        }
        static void M2(string msg)
        {
            Console.WriteLine(msg);
        }
        static void M3(string msg)
        {
            Console.WriteLine(msg);
            Console.WriteLine("第3个方法。。");
        }
        static void M4(string msg)
        {
            Console.WriteLine(msg);
        }
        static void M5(string msg)
        {
            Console.WriteLine(msg);
        }
View Code

示例:

 class Program
    {
        static void Main(string[] args)
        {
            #region 多播委托

            ////一般第一个要使用=赋值,后续的方法可以使用+=来赋值。
            //Action<string> action = M1;
            //action += M2; //表示添加一个委托的引用 
            //action += M3;
            //action += M4;
            //action += M5;//action -= M3;//表示去除一个委托的引用
            if(action!=null){//防止为空,报错
             action("xxx");//一次性触发全部的方法。调用顺序不一定哦。
}
//Console.ReadKey(); #endregion MyDelegate md = new MyDelegate(T1); //为什么这么写呢?等下取消注释上面的代码反编译之后放截图就知道 md = (MyDelegate)Delegate.Combine(md, new MyDelegate(T2), new MyDelegate(T3)); // md(); 下面的方法是获取所有注册的方法逐个调用 Delegate[] delegates = md.GetInvocationList(); for (int i = 0; i < delegates.Length; i++) { (delegates[i] as MyDelegate)(); } Console.ReadKey(); //使用队列试试 //Queue<MyDelegate> queue = new Queue<MyDelegate>(); //queue.Enqueue(new MyDelegate(T1)); //queue.Enqueue(T2); //queue.Enqueue(T3); //queue.Dequeue(); //queue.Dequeue(); //queue.Dequeue(); }

多播委托反编译:可看到,本质就是调用Delegate.Combine方法组装起来的,调用的时候为什么能全部触发已注册的方法?可以看到编译器调用GetInvocationList方法之后得到委托父类数组循环逐个调用; 事件的本质我们稍后探讨,跟多播密不可分

 

委托泛型委托多播委托匿名函数lamda表达式事件

1、为什么要使用委托  将一个方法作为参数传递给另一个方法2、委托概念  publicdelegateint委托名(inta,intb);  声明一个委托类型,可以用访问修饰符修饰,delegate关键字,有返回值和参数  委托所指向的函数必须跟委托具... 查看详情

c#规范整理·泛型委托事件(代码片段)

...它减少了泛型类及泛型方法中的转型,确保了类型安全。委托本身是一种引用类型,它保存的也是托管堆中对象的引用,只不过这个引用比较特殊,它是对方法的引用。事件本身也是委托,它是委托组,C#中提供了关键字event来... 查看详情

多播委托(代码片段)

多播委托,顾名思义即使一个委托引用多个方法举列staticvoidTest1Console.writLine(“test1”);staticvoidTest2Console.writLine("test2");staticvoidMain(string[]args)Actiona=Test1;a+=Test2//添加一个委托的引用所以删除一个委托的应用为a-=Te 查看详情

委托多播

usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;namespace多播委托{publicdelegatevoidDele();classProgram{staticvoidMain(string[]args){Deledel=showM 查看详情

c#学习(10):委托

1。疑问:1.委托是什么?2.为什么需要委托?3.委托能用来做什么?4.如何自定义委托?5..NET默认的委托类型有哪几种?6.怎样使用委托?7.多播委托是什么?8什么是泛型委托?9.什么是匿名方法?10.委托是否可以回调实例方法?11.L... 查看详情

Delegate.Combine:如何检查多播(可组合)委托中是不是已经有委托?

】Delegate.Combine:如何检查多播(可组合)委托中是不是已经有委托?【英文标题】:Delegate.Combine:HowtoCheckifmulticast(combinable)delegatesalreadyhasadelegateinsideofit?Delegate.Combine:如何检查多播(可组合)委托中是否已经有委托?【发布时... 查看详情

多播委托

首先定义两个委托和几个方法,后面会用到。委托:1publicdelegatevoidM1Delegate();23publicdelegateintM2Delegate(intx,inty);ViewCode方法:1staticintA1(intx,inty)2{3returnx+y;4}56staticintA2(intx,inty)7{8returnx+y;9}1011staticintA3( 查看详情

按自己的想法去理解事件和泛型(c#)

上一篇那些年困扰我们的委托(C#)讲了委托,这一篇自然就轮到事件了。不喜欢官方的表达方式,喜欢按照自己的想法去理解一些抽象的东西,我是一个喜欢简单怕麻烦的人。事件考虑到委托使用的一些缺陷,就有了事件。委托... 查看详情

c#进阶多播委托和委托数组像是一回事~

这个MathOperation类有三静态方法,参数都是double,并且没有返回值,考虑用Action<>()这种预定义的委托哦classMathOperations{publicstaticvoidMultiplyByTwo(doublevalue){Console.WriteLine("2*{0}={1}",value,value*2);}publicstaticvoidSquar 查看详情

c#中的委托是啥?事件是否一种委托?

委托就好比你委托某人帮你做某件事情,只不过这个是委托给方法罢了,事件是一种特殊的委托...参考技术A本节内容参考《你必须知道的.NET》和《C#高级编程(第四版)》一、了解委托我们知道回调函数实际上就是方法调用的... 查看详情

c#多播委托和事件有啥区别

感觉功能上一模一样啊。参考技术A事件是对委托的封装。如果一个类里,你把一个委托声明为public了,那么外部就可以随意改变委托变量的值,包括清空委托变量等,这样的话就违背了面向对象思想的封装特性;但如果声明为pr... 查看详情

委托和事件

本文目录:委托   委托的简单使用   用委托实现插件式编程   多播委托   静态方法和实例方法对于委托的区别   泛型委托   Func和Action委托   委托的... 查看详情

iPhone - 在泛型类中引用应用程序委托

】iPhone-在泛型类中引用应用程序委托【英文标题】:iPhone-Referencingtheapplicationdelegatewithinagenericclass【发布时间】:2011-07-3013:29:31【问题描述】:我正在编写一个可以通过链接在不同项目中使用的通用类。在某个时刻,我在一个监... 查看详情

泛型委托

usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;namespace委托{classProgram{staticvoidMain(string[]args){#region不带返回值的泛型委托//Action<int,int> 查看详情

泛型委托学习进程

首先先回顾委托的使用过程步骤:委托使用总结:(1)    委托声明(定义一个函数原型:返回值+参数类型和个数)注:在类的外部——中介(房产中介商)(2)    根据委托定义“具体”的方法—... 查看详情

泛型委托

usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;namespace泛型委托{publicdelegateintDelCompare<T>(Tt1,Tt2);//publicdelegateintDelCompare(obje 查看详情

kotlin小知识之泛型和委托(代码片段)

文章目录泛型和委托泛型的基本用法类委托和委托属性类委托委托属性实现一个自己的lazy函数泛型和委托泛型的基本用法Kotlin当中的泛型机制和Java当中的泛型机制还是有异同的所谓泛型就是说在一般的编程模式下面,我们需要给... 查看详情

c#语言中泛型和委托的关系是啥,func<int>是泛型还是委托?

C#语言中泛型和委托的关系是什么,Func是泛型还是委托?参考技术AFunc既是泛型也是委托。表示一个没有参数,有int返回值的函数。 查看详情