引言
委托是进阶C#重要的必学内容,为更进一步理解C#委托的使用方式及意义,故写了此篇个人学习笔记加深理解和记忆。
一、C#提供的委托
1、Action
实例化某个类以后,再new出一个Action实例接收类里的方法,即可实现方法的间接调用。这里的方法无返回值。
class ActionLearn
{
static void Main(string[] args)
{
Calculator calculator = new Calculator();
Action action = new Action(calculator.Report);
action.Invoke();
//action(); 使用指针式写法也可以
}
}
class Calculator
{
public void Report()
{
Console.WriteLine("间接调用Report方法");
}
public int Add(int x, int y)
{
return x + y;
}
public int Sun(int x, int y)
{
return x - y;
}
}
2、Func<>泛型委托
C#提供的泛型委托,有很多个方法重载可选用。这里的方法是有返回值的。
class ActionLearn
{
static void Main(string[] args)
{
Calculator calculator = new Calculator();
Func<int,int,int> func1 = new Func<int,int,int>(calculator.Add);
Func<int,int,int> func2 = new Func<int,int,int>(calculator.Sub);
var z = func1.Invoke(100,200);
console.WriteLine(z);
var z = func2.Invoke(100,200);
console.WriteLine(z);
//func1e(100,200); 使用指针式写法也可以
}
}
class Calculator
{
public void Report()
{
Console.WriteLine("间接调用Report方法");
}
public int Add(int x, int y)
{
return x + y;
}
public int Sub(int x, int y)
{
return x - y;
}
}
二、自定义委托
- 委托是一种类,类是一种数据类型,所以委托也是一种数据类型。自定义委托的声明是为了照顾可读性和C/C++传统
- 委托的声明位置为命名空间下,注意防止在错误位置生成非预期的嵌套委托
- 委托与所封装的方法必须类型兼容,参数个数和参数类型一致,参数名可以不一致。
namespace Xxx
{
//声明一个委托,括号里是所封装方法参数列表,
public delegate double Calc(double x, double y);
class ActionLearn
{
static void Main(string[] args)
{
Calculator calculator = new Calculator();
Calc calc1 = new Calc(calculator.Add);
Calc calc2 = new Calc(calculator.Sub);
Calc calc3 = new Calc(calculator.Mul);
Calc calc4 = new Calc(calculator.Div);
double x = 100;
double y = 200;
double z;
z = calc1.Invoke(x,y); //也可以直接使用calc1(x,y);
Console.WriteLine(z);
}
}
class Calculator
{
public double Add(double x, double y)
{
return x + y;
}
public double Sub(double x, double y)
{
return x - y;
}
public double Mul(double x, double y)
{
return x * y;
}
public double Div(double x, double y)
{
return x / y;
}
}
}
三、委托的使用
1、一般使用
- 模板方法,“借用”指定的外部方法来产生结果
- 回调方法(callback),调用指定的外部方法
2、多路广播委托
- 派生于
Syetem.MulticastDelegate
- 可使用
+=
和-=
将方法加入或者取出委托中。 - 声明时必须返回void,否则返回值返回的是最后一个加入委托的方法的返回值,编译不会出错。
3、为什么使用委托?
将方法的引用封装在委托对象中,把委托对象作为其他方法的参数使用,这里把方法的过程也看作对象去调用,符合面向对象编程思想。