一、委托类型和委托实例
1、委托类型
委托类型定义了委托实例可以调用的那类方法,具体来说,委托类型定义了方法的返回类型和参数。
delegate int Transformer(int x)
- int 返回类型
- Transformer 委托类型
- (int x) 参数
2、委托实例
Transformer t = Square ;
- t 委托实例
3、调用
int answer = t(3); //answer is 9
二、多播委托
一个委托实例可以引用一组目标方法
1、合并实例委托
+和+=操作符可以合并委托实例
SomeDelegate d = SomeMethod1;
d += SomeMethod2;
三、实例方法目标
当一个实例方法被赋值给委托对象的时候,这个委托对象不仅要保留着对方法的引用,还要保留着方法所属实例的引用。
class Program
{
delegate void ProgressReporter(int x);
class X
{
public void InstanceProgress(int percentcomplete) => Console.WriteLine(percentcomplete);
}
static void Main(string[] args)
{
X x = new X();
ProgressReporter p = x.InstanceProgress;
p(99);
Console.WriteLine(p.Target == x); //True 方法所属实例
Console.WriteLine(p.Method); //Void InstanceProgress(Int32) 方法
Console.ReadLine();
}
}
四、泛型委托类型
委托类型可以包含泛型类型参数
public delegate T Transformer<T> (T arg);
- 返回类型是T,参数也是T
public delegate T Transformer<T>(T arg);
public class Util
{
public static void Transform<T>(T[] values, Transformer<T> t) //参数: 一个数组 , 一个委托类型
{
for (int i = 0; i < values.Length; i++)
{
values[i] = t(values[i]);
}
}
}
class Program
{
static void Main()
{
int[] values = { 1, 2, 3 };
Util.Transform<int>(values, Square); // Util.Transform(values, Square); 可以这样子简写,可以通过参数推断
//经过调用Transform之后,values的值已经变了
foreach (int i in values)
{
Console.Write(i + " ");
}
Console.ReadLine();
}
static int Square(int x) => x * x;
}
五、Func 和 Action 委托
- Action 无返回值
- Func 有返回值
class Program
{
static void Main()
{
Action action1 = new Action(M1);
action1();
Action<string, int> action2 = new Action<string,int>(SayHello);
action2("zhonglq",18);
Func<int, int, int> func_add = new Func<int, int, int>(Add);
Console.WriteLine(func_add(2, 3)); //5
Func<double, double, double> func_mul = new Func<double, double, double>(Mul);
Console.WriteLine(func_mul(2, 3)); //6
Console.ReadKey();
}
static void M1()
{
Console.WriteLine("M1 is called");
}
static void SayHello(string name,int round)
{
Console.WriteLine(name + round);
}
static int Add(int x,int y)
{
return x + y;
}
static double Mul(double x,double y)
{
return x * y;
}
}
六、lambda表达式
两个知识点的交集
- 匿名方法
- inline方法 (调用时才声明的方法)
逐渐简化的过程
Func<int, int, int> f = new Func<int, int, int>((a, b) => { return a + b; });
Console.WriteLine(f(5, 3));
Func<int, int, int> f1 = (a, b) => { return a + b; }; //去掉了委托的new
f1 = (x, y) => { return x * y; };
泛型方法+泛型的委托类型参数+泛型参数
class Program
{
static void Main()
{
DoSomeCalc<int>((int a, int b) => { return a * b; }, 100, 200);
DoSomeCalc<int>((a,b) => { return a * b; }, 100, 200); //根据100 和200 可以推断 泛型委托的类型参数推断
Console.ReadKey();
}
static void DoSomeCalc<T>(Func<T,T,T> func,T x,T y)
{
T res = func(x, y);
Console.WriteLine(res);
}
}