委 托 委托 委托
C#委托之类间互调函数
委托的作用:双方的信息的桥接(因为双方直接传递信息存在障碍)
程序中的问题:有时候一个对象,想访问另一个对象,可能正常情况下无法达到要求。
特别是两个对象相互调用,你中有我,我中有你,就会无限循环,卡死。也编译不过。
所以面向对象编程中,我们使用对象的时候,要特别注意对象之间消息的传递问题。
但如果我必须完成这个两个类对象互相获取对方函数的需求,怎么办?
委托诞生了。(有人会想到静态方法,但是静态方法有时候是不可行的)
程序中的委托(delegate):是一种程序特性,这种特性是针对方法而言的。也就说委托是方法的指针(代表),换句话说,方法可以作为参数传递。
委托的基本使用
【1】声明委托类型:定义一个方法的原型(方法返回值类型、参数类型和个数)
【2】定义委托方法
【3】创建委托变量
【4】关联委托变量(3,4可以合并在一起)
【5】使用委托变量
1.public delegate void TestDelegate(int a ,int b);
2.static void Add(){}
3.TestDelegate testDele = null;
4.testDele += Add;
5.testDele(100,200)
委托的动态关联
+=
-=
如果我们想去掉一个方法的关联,直接用-=即可。这个在委托和事件中非常有用。
委托的应用
- 如果一个委托关联了多个方法,当我们使用委托变量的时候,会按照关联方法的顺序,依次调用方法。这种委托,我们称为多路委托(多播委托)
委托与多态(委托类型作为方法参数)
static void Test3(calculatorDelegate1 myDelegate){
//基于委托实现多态的话,方法需要的参数,会在这个地方获取....
myDelegate(6.6,9.99); // 看这个你根本不知道你对这两个数做什么操作
}
实际开发中下面的多态实现一般和上面不在一起
static void CallTest3(0{
Test3(Add);//直接将一个方法作为参数传递过去
Test3(delegate(double a,double b){ print("test") })
}
系统委托
系统委托使用:我们知道,如果我们想将方法作为参数传递,你必须要首先声明委托!
其实,我们声明的委托,无非就是没有参数、一个参数,多个参数;有返回值,没有返回值。
实际开发中,你如果用的委托非常多,你就得不断的声明各种委托。
针对有返回值的,和没有返回值的情况。
平台给我们提供了两种系统委托,可以直接使用。Action 和 Func
不需要再声明委托
。而是直接使用Action
和 Func
public void Add(double a ,double b)
{
a + b
}
Action<double, double> myAction = Add; //使用系统委托直接声明我们需要的“委托”
myAction(2.3,4.6);
委托多态的实现可以改成系统委托
在基于委托实现多态的时候,更加方便
static void Test2(Action<double, double> myAction){
)
委托在多线程中的应用
委托学习关系链:自定义委托–>系统委托–>匿名方法–>Lambda表达式–>多线程应用
委托
,和类、接口、int、string一样属于一种类型
委托是引用类型
委托(Delegate)是存有对某个方法的引用的一种引用类型变量。
引用可在运行时被改变。用于将方法作为参数传递给其他方法
。
委托是一个类,它定义了方法的类型
换句说法:委托是一个类,它定义了方法的类型(比如String类,定义了字符串的类型),使得可以将方法当作另一个方法的参数来进行传递,这种将方法动态地赋给参数的做法,可以避免在程序中大量使用lf- Else(Switch)语句,同时使得程序具有更好的可扩展性。
需要注意的是在定义时参数类型和个数要与你想委托的方法一致。
使用委托可以将多个方法
绑定到同个委托变量
,当调用此变量时(这里用“调用”这个词,是因为此变量代表一个方法),可以依次调用所有绑定的方法
。
1.方法的描述
委托,delegate ,是C#中一种回调的实现
-对应C++/Qt里的槽
C#委托的四种形式(delegate、Action、Func、predicate)
(1)delegate
Delegate至少0个参数,至多32个参数,可以无返回值,也可以指定返回值类型。
public delegate int MethodDelegate(int x, int y);
private static MethodDelegate method;
static void Main(string[] args)
{
method = new MethodDelegate(Add);
Console.WriteLine(method(60,20));
Console.ReadKey();
}
private static int Add(int x, int y)
{
return x + y;
}
(2)Action
Action是无返回值的泛型委托。至少0个参数,至多16个参数,无返回值
static void Main(string[] args)
{
Test<string>(Action,"Hello World!");
Test<int>(Action, 1000);
Test<string>(p => { Console.WriteLine("{0}", p); }, "Hello World");//使用Lambda表达式定义委托
Console.ReadKey();
}
public static void Test<T>(Action<T> action, T p)
{
action(p);
}
private static void Action(string s)
{
Console.WriteLine(s);
}
private static void Action(int k)
{
Console.WriteLine(k);
}
(3)Func
Func是有返回值的泛型委托。 Func至少0个参数,至多16个参数,根据返回值泛型返回。必须有返回值,不可void。
(4) predicate
predicate 是返回bool型的泛型委托。Predicate有且只有一个参数,返回值固定为bool
在C#里面,如何描述一个方法呢?
1 参数类型列表
2 返回值类型
比如,
public void test1(int a)
“一个参数为(int)的、返回值为void的方法”
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CSharp基础语法
{
public class Example
{
public void test1(int a)
{
Console.WriteLine("test1:" + a);
}
public void test2(int b)
{
Console.WriteLine("test2:" + b);
}
public int test3(int m)
{
Console.WriteLine("test3:" + m);
return m * m;
}
public int test4(int a)
{
Console.WriteLine("test4:" + a);
return a + a;
}
public int test5(int x,int y)
{
return x + y;
}
}
}
1对test1(), test2(), test3(), test4(), test5()进行描述
2对此五个方法进行规类
可以发现,test1,test2同属一类,test3,test4同属一类
2.委托 delegate
委托,delegate,是一个对方法类型的描述
例如:
public delegate void DFunction(int a);
则DFunction类型指的是“一种参数为(int)、返回值为void的方法”
类比一下,会更易懂:
public class Student{}
public interface Player{}
public delegate void DFunction (int a);
其中,delegate声明它是个委托类型,DFunction是类型的名字。
一个委拖对象,就是一个方法的实例例如:
DFurction d = new DFunction(ex.test1);
d(18);
传参时,要指定某个对象的某个方法
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CSharp基础语法
{
public class Example
{
public void test1(int a)
{
Console.WriteLine("test1:" + a);
}
public void test2(int b)
{
Console.WriteLine("test2:" + b);
}
public int test3(int m)
{
Console.WriteLine("test3:" + m);
return m * m;
}
public int test4(int a)
{
Console.WriteLine("test4:" + a);
return a + a;
}
public int test5(int x,int y)
{
return x + y;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CSharp基础语法
{
// 第一类方法
public delegate void NumberOneFunction(int a);
// 第二类方法
public delegate int NumberTwoFunction(int b);
// 第三类方法
public delegate int NumberThreeFunction(int a, int b);
class Program
{
static void Main(string[] args)
{
Example ex = new Example();
NumberOneFunction num1 = new NumberOneFunction(ex.test1);
num1(18); // == ex.test1(18)
}
}
}
3.委拖的更多用法
1委托的调用,以下两种方式等效:
DogFunction dog =new DogFunction(ex.Test);
dog(18);
dog.Invoke(18);
其中:dog是一个委托(方法),dog(18)就是调用这个方法,dog.Invoke(18)也是调个方法。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CSharp基础语法
{
public class Example
{
// 实例方法
public void Test(int a)
{
Console.WriteLine("Test:" + a);
}
// 静态方法
public static void Print(int a)
{
Console.WriteLine("Print:" + a);
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CSharp基础语法
{
// 第一类方法
public delegate void NumberOneFunction(int a);
class Program
{
static void Main(string[] args)
{
Example ex = new Example();
// 实例方法的调用
NumberOneFunction num1 = new NumberOneFunction(ex.Test);
num1(100);
num1.Invoke(100);
静态方法的调用
NumberOneFunction num11 = new NumberOneFunction(Example.Print);
num11(1100);
num11.Invoke(1100);
}
}
}
3委拖是一种类型,可以和 class, interiface同级定义
public delegate void DFunction (int a);
public class YourClass {};
也可以作为内部类型
public class YourClass{
public delegate void DFunction (int a);}
全称:YourNameSpace.YourClass.DFunction