1. 委托
如果我们要把方法当作参数来传递的话,就需要用委托。简单说,委托是一个类型,这个类型可以复制一个方法的引用。
声明委托:
delegate void method(int x, string y); //注意是方法签名
class Program{ private delegate string Getstring(); //定义委托
static void Main(string[] args)
{ int x = 40;
Getstring a = x.ToString; //a指向了x中的Tostring方法,没有调用方法,
//注:Getstring a = new Getstring(x.ToString)这样也可以
string s = a(); //通过委托去调用x中的tostring方法。
Console.WriteLine(s);
Console.ReadKey();
}
namespace ConsoleApplication1
{ class program
{
delegate double Deloperate(double num1, double num2); //声明委托,名字随便
static void Main(string[] args)
{ Deloperate delop = new Deloperate(Add); //实例化委托
double results = delop(2.3, 5.6); //委托调用方法,delop.Invoke(2.3,5.6)也可以
Console.WriteLine(result);
Console.ReadKey();
}
static double Add(double a, double b)
{
return a + b;
}
2. Action委托
只能指向一个无返回值的方法。
static void Print()
{
Console.WriteLine("Hello world");
}
static void Print2(int i, int j)
{
Console.WriteLine(i+j);
}
static void Main(string[] args)
{
Action a = Print; // 或者 Action a = new Action(Print);
a();
Action<int, int> a = Print; //参数类型要对应,还是没有返回值;Action<T>是Action的泛型实现
a(12,34);
Console.ReadKey();
}
3. 多播委托(委托链)
static void Test1()
{
Console.WriteLine("test1");
}
static void Test2()
{
Console.WriteLine("test2");
}
static void Main(string[] args)
{
Action a = Test1;
a += Test2; //多播委托就是同时指向多个方法,注意
a();
Console.ReadKey();
}
4. Func委托
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; //必须要有返回值
Console.WriteLine(a());
Func<string, int> b = Test2; //必须要对应
Console.WriteLine(b("fuck"));
Func<int, int, int> c = Test3; //两个参数,一个返回值,一一对应
Console.WriteLine(c(2, 3));
Console.ReadKey();
}
===============================================================================================
委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递,这种将方法动态地赋给参数的做法,可以避免在程序中大量使用if-else(switch)语句,同时使得程序具有更好的可扩展性。
使用委托可以将多个方法绑定到同一个委托变量上(通常称这个委托变量为:委托链),当调用此变量时,会依次调用所有绑定的方法;于此同时,也可以通过类似绑定的方式删除方法。
using System; using System.Collections; namespace Delegate { //用delegate关键字声明一个委托 //委托原型必须与预委托的方法具有相同的返回值和参数类型 delegate void MyDelegate(string name); public class Test {
//要进行委托的方法 static void LearnA(string name) { Console.WriteLine("小王在学" + name); } static void LearnB(string name) { Console.WriteLine("小张在学" + name); } static void Main() { //创建委托实例,并把委托函数名当作参数传递给委托对象 MyDelegate delegate1 = new LearnDelegate(LearnA); MyDelegate delegate2 = new LearnDelegate(LearnB); //通过委托对象,给绑定的函数传递参数,其实现在的learn_A和learn_B就是learnA和learnB的函数别名 delegate1("C#"); gelegate2("C++"); } } }
委托链
static void Main() { //创建委托实例 LearnDelegate learn_A = new LearnDelegate(LearnA); LearnDelegate learn_B = new LearnDelegate(LearnB); //声明一个委托链,不需要实例化它 LearnDelegate DelegateLst; //把委托对象直接相加并赋给委托链 DelegateLst = learn_A + learn_B; //给委托链传值 DelegateLst("编程"); Console.WriteLine(); //同样,也可以对委托链中的委托对象进行添加和删除操作 DelegateLst -= learnA;//删除一个委托方法,这里使用DelegateLst -= Learn_A;效果是一样的,因为此时可以看作它是LearnA方法的一个别名 DelegateLst("编程"); Console.WriteLine(); DelegateLst += learnB;//添加一个委托方法,同样这里也可以使用DelegateLst += Learn_B; DelegateLst("编程"); }
委托链的简化使用
using System; using System.Collections; namespace Delegate { //用delegate关键字声明一个委托 //委托原型必须与预委托的方法具有相同的返回值和参数类型 delegate void LearnDelegate(string name); public class Test { static void Main() { //声明一个委托链,赋null值 LearnDelegate DelegateLst = null; //下面这种形式其实是匿名方法的一种应用 DelegateLst += delegate(string name) { Console.WriteLine("小王在学" + name); }; DelegateLst += delegate(string name) { Console.WriteLine("小张在学" + name); }; DelegateLst("编程"); } } }
最后的一个例子
using System; using System.Collections; namespace Delegate { //用delegate关键字声明一个委托 //委托原型必须与预委托的方法具有相同的返回值和参数类型 delegate void AnimalDelegate(string AnimalName); class Animal { public Animal() { } //要进行委托的方法 public void Miaow(string name) { Console.WriteLine( name + " 喵喵叫"); } //要进行委托的方法 public void Bark(string name) { Console.WriteLine(name + " 汪汪叫"); } //要进行委托的方法 public void Baa(string name) { Console.WriteLine(name + " 咩..."); } } public class MainFunc { static void choseAnimal(string name, AnimalDelegate delegateFun) { delegateFun(name); } static void Main() { /*AnimalDelegate cat = new AnimalDelegate(new Animal().Miaow); cat("猫咪"); AnimalDelegate dog = new AnimalDelegate(new Animal().Bark); dog("狗狗");*/ //上下的两种调用方式是等价的 choseAnimal("喵星人", new Animal().Miaow); choseAnimal("汪星人", new Animal().Bark); choseAnimal("喜洋洋", new Animal().Baa); } } }