using System;
namespace 委托
{
class Program
{
//委托类型:定义了委托实例可以调用哪类方法,
//具体来说,委托类型定义了方法的返回值类型了参数
//delegate 要调用方法的返回值类型 委托类型名 (参数)
//例:定义一个带参数,无返回值的委托
//(创建的委托必须与索要传递的方法,返回值/参数类型相同)
public delegate void SayHelloDlg(string content);
//SayHelloDlg类型的事件,声明事件,public event 委托类型 事件名
public static event SayHelloDlg SayHelloEvent;
//主函数
static void Main(string[] args)
{
//委托的声明
//委托类型名 = 目标方法
SayHelloDlg dlg = SayHello;
//委托的使用方法
//dlg.Invoke("老王");
dlg("老王");
//委托的解释:将方法以变量形式传递,并以方法形式执行。(以委托来调用方法,解耦)
//SayHelloDlg dlg = new SayHelloDlg(SayHello);
//(多播委托)委托链
dlg += SayBay;//添加
dlg("老八"); //(实际+,-,+=,-+编译成 System.Delegate的Combine和Remove两个静态方法)
dlg -= SayBay;//注销
dlg("老八");
//如果调用的方法有返回值,那么接收的返回值是调用的最后一个方法的返回值,前面调用的方法返回值就被舍弃了。
//匿名函数
SayHelloDlg dlg1 = delegate (string name)
{
Console.WriteLine("{0},是匿名函数", name);
};
dlg1("老七");
//lamda语句
SayHelloDlg dlg2 = (name) =>
{
Console.WriteLine("{0},是lamda语句", name);
};
dlg2("老四");
//事件
**事件不能在类的外部进行调用(委托可以),但可在类的外部注册。因此事件更安全**
**事件委托区别**
**事件使用与委托基本一致,事件是对委托的封装,使用更安全**
**主要区别**
**1.事件不能在外部使用赋值负号"=",只能进行+,-,进行事添加与注销,委托那里都能使用**
**2.事件不能在外部执行,委托在那里都能执行**
**3.事件 不能作为函数中的临时变量,只能在类/结构体中的成员变量,委托可以作为临时变量**
//注册事件
// SayHelloEvent += new SayHelloDlg(Program_SayHelloEvent);//实际事件上挂的是委托链对象
SayHelloEvent += Program_SayHelloEvent;//上行代码简写
//SayHelloEvent -= Program_SayHelloEvent;
if (SayHelloEvent != null)
{
SayHelloEvent("小八");//调用事件
}
}
private static void Program_SayHelloEvent(string content)
{
Console.WriteLine("{0},是事件", content);
}
public static void SayHello(string name)
{
Console.WriteLine("{0},你好啊", name);
}
//表达式形式
//public static void SayHello(string name) => Console.WriteLine("{0},你好啊", name);
public static void SayBay(string name)
{
Console.WriteLine("{0},再见啊",name);
}
}
}
//Part2-----------------------------------------------------------------------
泛型委托,
Action,无返回值
using System;
namespace System委托
{
class Program
{
static void Main(string[] args)
{
Action a = PrintString;//系统预定义的无返回值的委托类型,可指向一个无参数,返回值的方法
Action<int> b = PrintInt;//泛型Action定义了一个委托,可指向有一个int类型参数,无返回值方法
PrintInt(1);
Action<string> c = PrintString;//泛型Action定义了一个委托,可指向有一个string类型参数,无返回值方法,
//(存在重名方法时系统会自动匹配)合适的方法
PrintString("Get");
Action<int, int> d = PrintInt;//最多可附带16个参数,
PrintInt(2, 3);
}
static void PrintString()
{
Console.WriteLine("Action委托");
}
static void PrintString(string a)
{
Console.WriteLine("Action委托" + a);
}
static void PrintInt(int a)
{
Console.WriteLine(a);
}
static void PrintInt(int a, int b)
{
Console.WriteLine(a + b);
}
}
}
Func,有返回值(返回值为最后一个泛型的参数)
static void Main(string[] args)
{
Func
Console.WriteLine(a());
Func<int, int, string> b = Fun2;//多个泛型时,最后一个泛型为返回值类型,
//前面的泛型与参数类型一一对应。
Console.WriteLine(b(2, 3));
}
static int Fun1()
{
return 1;
}
static string Fun2(int a,int b)
{
return (a + b).ToString();
}
多播委托-----又返回值时只返回最后一个方法的返回值,中间方法出现异常时,后面的方法将不会被调用
static void Text1()
{
Console.WriteLine("Text1");
}
static void Text2()
{
Console.WriteLine("Text2");
}
static void Main(string[] args)
{
Action a = Text1;
a += Text2;//多播委托(委托链),可指向多个与委托同类型的方法
a();
a -=Text2;//注销一个委托链上的方法,当一个委托没有指向任何方法时注销会异常
if (a != null)
a();
//多播委托方法
Delegate[] delegates = a.GetInvocationList();//返回该委托中所有方法的单独委托(解耦)
foreach (var /*Action*/ d in delegates)
{
d.DynamicInvoke();//获取委托后单独执行//有参数时可填入括号
}
}
//匿名方法
static int Text1(int a,int b)
{
return a + b;
}
static void Main(string[] args)
{
//Func<int, int, int> a = Text1;
Func<int, int, int> a = delegate (int a, int b)//delegate定义 匿名方法(只使用一次时,通常用于回调函数(动作完成后执行))
{
return a + b;
};
//Lambda表达式--用来代替匿名方法
Func<int, int, int> a = (a, b) =>//不需在指定类型(委托中以指定类型)
{
return a + b;
};
Console.WriteLine(a(2, 3));
Func<int, int> text2 = a => a+= 1;//lambda表达式只有一个参数时参数可不加括号,当函数体只有一句时,也可不写大括号,
//需要也可不加上return语句,可自动取值。
/*Func<int, int> text3 = (a) =>//text2完整形式
{
return a += 1;
};*/
Console.WriteLine(text2(2));
//Lambda表达式可访问外部变量(应用不安全,返回值不只有参数决定谨慎使用)
int someValue = 5;
Func<int, int> outValue = x => x += someValue;
Console.WriteLine(outValue(5));
someValue = 15;
Console.WriteLine(outValue(5));
}