委托
委托类似于CPP中的函数指针。它定义了一个方法类型,这个方法类型有返回类型和形参,不需要方法体,但是在声明这个方法类型时要添加delegate
关键字
1. 基本用法
切换委托的方法指向,从而执行不同方法。
namespace TopSet
{
internal class Program
{
//声明委托类型
delegate int MethodTypeOfDelegate(int a, int b);
static void Main(string[] args)
{
//给委托类型赋值
MethodTypeOfDelegate mt = Add;
Console.WriteLine(mt(1,2));
mt = Dec;
Console.WriteLine(mt(2,1));
Console.ReadLine();
}
static int Add(int a,int b)
{
return a + b;
}
static int Dec(int a,int b)
{
return a - b;
}
}
}
--输出
3
1
2.委托作为方法参数
委托类型作为某个方法的参数传入
namespace TopSet01
{
internal class Program
{
//声明委托类型
delegate int MethodTypeOfDelegate(int a);
static void Main(string[] args)
{
int a = 5;
//传入
MultiValue(ref a, Add);
Console.WriteLine(a);
Console.ReadLine();
}
//委托类型作为参数
static void MultiValue(ref int a,MethodTypeOfDelegate mt)
{
a = mt(a);
}
static int Add(int a)
{
return a * a;
}
}
}
3.多播委托
多播委托就是把需要按照顺序执行的,相同类型的委托方法加到一起,执行的时候会按照顺序执行所有的委托方法。可以用于控制台和日志文件的输出。
下方案例仅供演示用法,具体问题需要灵活变通后使用。
namespace TopSet02
{
public delegate void MethodTypeOfDelegate(int a);
public class Util
{
public static void PrintSquence(int a,MethodTypeOfDelegate mt)
{
mt(a);
}
}
internal class Program
{
static void Main(string[] args)
{
MethodTypeOfDelegate? mt = null;
//加起来,按照加入的顺序执行
mt += PrintSelf;
mt += PrintMul;
int a = 5;
Util.PrintSquence(a, mt);
Console.ReadLine();
}
static void PrintSelf(int a)
{
Console.WriteLine(a);
}
static void PrintMul(int a)
{
Console.WriteLine(a*a);
}
}
}
--输出
5
25
4.实例对象方法、静态方法与委托之间的关系
这里实例对象方法指的是 new 出来的一个对象,它的方法赋值给委托变量。委托变量不仅可以调用该方法,而且委托变量还能获取到这些对象方法所对应的对象。如果是静态方法赋值给委托变量,无法获取对应的对象,对象方法可以。
namespace TopSet03
{
public delegate void MethodTypeOfDelegate(int a);
public class StaticMethodClass
{
public static void PrintSelf(int a)
{
Console.WriteLine("here is static method: "+a);
}
}
public class NormalClass
{
public void PrintSelf(int a)
{
Console.WriteLine("here is normal method: " + a);
}
}
internal class Program
{
static void Main(string[] args)
{
MethodTypeOfDelegate? mt = null;
NormalClass nc = new NormalClass();
//可以获取到对象方法是来自哪一个类
mt = nc.PrintSelf;
Console.WriteLine((mt.Target==nc)+" :"+mt.Method);
//无法获取静态方法对应的类
mt = StaticMethodClass.PrintSelf;
Console.WriteLine(mt.Target == null);
Console.ReadLine();
}
}
}
--输出
True :Void PrintSelf(Int32)
True
5. 委托类型参数为泛型
这个和基本用法几乎一样,就是改个参数类型。
namespace TopSet04
{
public delegate T MethodTypeOfDelegate<T>(T a);
internal class Program
{
static void Main(string[] args)
{
MethodTypeOfDelegate<int> mti = Mul;
Console.WriteLine(mti(5));
MethodTypeOfDelegate<float> mtf = Mulf;
Console.WriteLine(mtf(3.0f));
Console.ReadLine();
}
static int Mul(int a)
{
return a * a;
}
static float Mulf(float a)
{
return a * a;
}
}
}
--输出
25
9
6. System空间下的 Func 委托和 Action 委托
Func和Action都是委托类型为参数的委托,是System提供的。
Func委托最后一个泛型类型必须是传出类型而且该委托的返回值必须是传出类型,即必须添加 out 标识符,如果只有一个泛型参数,那么这个泛型必须是 传出类型。
Action委托是返回值为空的,参数是泛型的委托。
namespace TopSet05
{
internal class Program
{
static void Main(string[] args)
{
Action<int, int> a = Add;
a(1, 2);
Func<int, int, int> f = Dec;
Console.WriteLine(f(2,1));
}
//Action类型
static void Add(int a,int b)
{
Console.WriteLine(a+b);
}
//Func类型,返回值为int
static int Dec(int a,int b)
{
return a - b;
}
}
}