using System;
using static System.Console;
//委托 降低耦合
//如果一个函数的参数是一个函数
//就可以定义一个委托
namespace ConsoleApp
{
class Program
{
//委托
//可以在类的内部、外部,名字空间 定义委托
//相当于一个函数类型
public delegate void WtiteAString(int i);
public static void fun(int i)
{
WriteLine(i);
}
public static void fun1()
{ }
static void Main(string[] args)
{
//复制会重新分配一个方法
WtiteAString write = fun;
write = new WtiteAString(fun);
write(1);
//Action<T>委托,返回类型为void
Action<int> op1 = fun;
op1(2);
Action d = fun1;
//Func<T>委托
//单参,表示返回类型,多参前面表示方法的参数,最后一个表示返回类型
Func<int, double> op2;
//多播委托,使用+ += - -=
//其调用的顺序并未正式定义,所以要避免写依赖顺序调用方法的代码
op1 += fun;
//如果委托调用的一个方法引发了异常,委托迭代就会停止,不再调用其他方法
//为避免这种情况,应自己迭代方法列表
Action d1 = fun1;
d1 += fun1;
Delegate[] delegates = d1.GetInvocationList();
foreach (Action d2 in delegates)
{
try
{
d2();
}
catch (Exception)
{
WriteLine("Exception caught");
}
}
//匿名方法 委托一个现写的函数
//匿名方法不能使用跳转语句(break goto continue)跳到该匿名方法外部
//不能访问外部ref、out参数,但可以使用其他的外部变量
string mid = ", middle part,";
Func<string, string> anonDel = delegate (string param)
{
param += mid;
param += " and this was added to the string.";
return param;
};
WriteLine(anonDel("start of string"));
//lambda表达式
Func<string, string> oneParam =
s2 => $"change uppercase {s2.ToUpper()}"; //s2为参数
WriteLine(oneParam("test"));
//多个参数
Func<double, double, double> twoParams =
(x, y) => x * y;
WriteLine(twoParams(2, 3));
}
}
}