using System;
namespace Lesson12_委托
{
#region 知识点一 委托是什么
//委托是函数的容器
//可以理解为方法表示函数(方法)的变量类型
//用来存储、传递函数(方法)
//委托的本质是一个类,用来定义函数(方法)的类型(返回值和参数的类型)
//不同的 函数(方法)必须对应和各自“格式”一致的委托
#endregion
#region 知识点二 基本语法
//关键字:delegate
//语法:访问修饰符 delegate 返回值 委托名(参数列表);
//写在哪里?
/* 可以声明在namespace或class语句块中
* 更多的是写在namespace中
*
* 简单记忆委托语法:函数声明前加一个delegate关键字
*/
#endregion
#region 知识点三 定义自定义委托
/* 访问修饰符默认不写时,为public,在引用命名空间后可以使用
* private,其他命名空间就不能使用了
* 一般使用public
*/
//声明了一个可以用来存储无参无返回值函数的容器
//这里只是定义了规则,未使用
public delegate void Myfun();
//委托规则的声明,是不能同名的(同一语句块中)
//表示用来装载或传递:返回值为int,有一个int参数的函数的 委托 容器规则
public delegate int Myfun2(int a);
//声明泛型委托, 可以让返回值和参数类型可变
//一般不自己声明,一般使用系统自带委托
public delegate T Myfun3<T, K>(T t, K k);
#endregion
#region 知识点四 使用定义好的委托
/* 委托变量是函数的容器
*
* 委托常用在:
* 1.作为类的成员
* 2.作为函数的参数
*/
class Test
{
public Myfun fun;
public Myfun2 fun2;
public void TestFun(Myfun _fun, Myfun2 _fun2)
{
//先处理一些别的逻辑,当这些逻辑处理完了,在执行传入的函数
int i = 1;
i *= 2;
i += 2;
//_fun();
//_fun2(1);
this.fun = _fun;
this.fun2 = _fun2;
}
#region 增
public void AddFun(Myfun fun, Myfun2 fun2)
{
this.fun += fun;
this.fun2 += fun2;
}
#endregion
#region 删
public void RemoveFun(Myfun fun, Myfun2 fun2)
{
this.fun -= fun;
this.fun2 -= fun2;
}
#endregion
}
#endregion
#region 知识点五 委托变量可以存储多个函数(多播委托)
#region 增
/* public void AddFun(Myfun fun, Myfun2 fun2)
{
this.fun += fun;
this.fun2 += fun2;
}*/
#endregion
#region 删
/*public void RemoveFun(Myfun fun, Myfun2 fun2)
{
this.fun -= fun;
this.fun2 -= fun2;
}*/
#endregion
#endregion
#region 知识点六 系统定义好的委托
//系统提供了很多常用委托
#endregion
class Program
{
static void Main(string[] args)
{
Console.WriteLine("委托");
#region 知识点四 使用定义好的委托
//专门用来 装载函数的 容器
Myfun f = new Myfun(Fun);
//使用,必须和委托声明时的规则一致
//通过Invoke调用
f.Invoke();
Myfun f2 = Fun;
f2.Invoke();
//f2 = Fun2; error Fun2 没有与委托Myfun匹配的重载
Myfun2 f3 = Fun2;
//像函数一样调用
Console.WriteLine(f3(1));
Myfun2 f4 = new Myfun2(Fun2);
Console.WriteLine(f4.Invoke(10));
Test t = new Test();
t.TestFun(Fun, Fun2);
#endregion
#region 知识点五 委托变量可以存储多个函数(多播委托)
#region 增
Console.WriteLine("***********增**************");
//如何用委托存储多个函数
Myfun ff = null; //委托可以有初始null值
ff += Fun;
ff += Fun3;
ff();
t.AddFun(Fun, Fun2);
t.fun();
t.fun2(10);
#endregion
Console.WriteLine("*************删**************");
#region 删
/* 注意,委托为赋初始值不可使用
Myfun ff2;
ff2 += Fun; //error
*/
/* 注意:委托赋初始值为null,删除不会报错,但是无处理
* Myfun ff3 = null;
* ff3 -= Fun;
*/
//从容器中删除指定函数
ff -= Fun;
ff -= Fun; //多减,不会报错,但是无处理
ff();
//清空容器
ff = null;
if (ff != null)
{
ff();
}
#endregion
#endregion
#region 知识点六 系统定义好的委托
//系统提供了很多常用委托
//需要引用using System;
//Action 委托
//封装一个方法,该方法不具有参数且不返回值。
//public delegate void Action();
Action action = Fun;
action += Fun3;
action();
//Func<TResult> 委托
//封装一个方法,该方法不具有参数,且返回由 TResult 参数指定的类型的值。
//public delegate TResult Func<out TResult>();
//out 表示返回值
Func<string> funcString = Fun4;
Func<int> funcInt = Fun5;
//Action<T> 委托
//封装一个方法,该方法只有一个参数并且不返回值。
//public delegate void Action<in T>(T obj);
//in 表示传入参数
//共有16个重载,即可以传递16个参数
Action<int, string, bool> actionN = Fun6;
//Func<T, TResult> 委托
//封装一个方法,该方法具有一个参数,且返回由 TResult 参数指定的类型的值。
//public delegate TResult Func<in T,out TResult>(T arg);
//共有17个重载,即可以传递16个参数,有一个返回值
Func<int, int> func2 = Fun2;
#endregion
#region pratice-1
Action familyDinner = null;
familyDinner += MotherCook;
familyDinner += FatherEat;
familyDinner += SonEat;
familyDinner();
#endregion
Console.WriteLine("*******pratic-2******");
#region pratice-2
Action updateAcchieve = null;
updateAcchieve += MonsterDead;
updateAcchieve += PlayerCoinAdd;
updateAcchieve += Update;
updateAcchieve += AchievementChange;
updateAcchieve();
#endregion
}
#region 函数
public static void Fun6(int a, string b, bool c)
{
Console.WriteLine("委托存储的Fun6函数,有多个参数");
}
static public int Fun5()
{
Console.WriteLine("委托存储的Fun5函数");
return -1;
}
static public string Fun4()
{
Console.WriteLine("委托存储的Fun4函数");
return "";
}
static public void Fun()
{
Console.WriteLine("委托存储的Fun函数");
}
static public void Fun3()
{
Console.WriteLine("委托存储的Fun3函数");
}
public static int Fun2(int num)
{
Console.WriteLine("委托存储的Fun2函数");
return num;
}
#endregion
#region pratice-1
public static void MotherCook()
{
Console.WriteLine("Monther cooks");
}
public static void FatherEat()
{
Console.WriteLine("Father eat");
}
public static void SonEat()
{
Console.WriteLine("Son eat");
}
#endregion
#region pratice-2
public static void MonsterDead()
{
Console.WriteLine("MonsterDead");
}
public static void PlayerCoinAdd()
{
Console.WriteLine("PlayerCoinAdd Ten");
}
public static void Update()
{
Console.WriteLine("Update");
}
public static void AchievementChange()
{
Console.WriteLine("AchievementChange");
AddMonsterKill();
}
public static void AddMonsterKill()
{
Console.WriteLine("AddMonsterKill");
}
#endregion
}
}
/* 总结
* 委托:就是装载、传递函数的容器
* 可以用委托变量,来存储函数或传递函数
* C#已经定义好了很多委托,Action和Func
* Action:无返回值,16个重载,即可以最多可以传递16个参数
* Func:有返回值,17个重载,即最多可以传递16个参数和一个返回值
*/
c# 进阶 委托
于 2023-06-17 11:21:58 首次发布
![](https://img-home.csdnimg.cn/images/20240711042549.png)