委托是什么
委托是 C# 独有的概念,委托的诞生是为了解决将函数作为参数去传递
是的,我们可以像下面这里 name 一样去传递函数了
代码语言:javascript复制public void test(string name)
{
Console.WriteLine(name);
}
public void test(? func)
{
func();
}
那我可以理解为委托是一个新类型吗?
委托的本质
准确的说,委托是一个类
代码语言:javascript复制public delegate void DelegateTest(int param);
// 最终翻译成一个类
public class DeletgateTest : System.MulticastDelegate
{
// ....
}
所以我们可以对委托去 new,它不就是一个类么
代码语言:javascript复制public delegate void DelegateTest(int param);
public void test()
{
DelegateTest del = new DelegateTest(Print);
del.invoke(1);
}
public void Print(int param)
{
Console.WriteLine(param);
}
委托的应用
一个日志记录实例,可以通过委托的方式去更改日志输出方式
代码语言:javascript复制class Program
{
static void Main(string[] args)
{
var logger = new Logger();
logger.Debug("测试1");
var logger2 = new Logger(msg => Console.WriteLine($"{DateTime.Now}: {msg}"));
logger2.Debug("测试2");
Console.ReadKey();
}
}
public delegate void OutPutAction(string msg);
public class Logger
{
public OutPutAction Output;
public Logger()
{
Output = new OutPutAction((msg) => Console.WriteLine(msg));
}
public Logger(OutPutAction outPutAction)
{
Output = outPutAction;
}
public void Debug(string msg)
{
Output(msg);
}
}
委托链
签名说的都是委托封装一个方法的情况,其实委托支持封装多个方法。C# 中把封装多个方法的委托称作委托链或多路广播委托
委托链的使用
委托链其实就是委托类型,只是委托链把多个委托链接在一起而已,也就是说,我们把链接了多个方法的委托称为委托链或多路广播委托
代码语言:javascript复制class Program
{
static void Main(string[] args)
{
var logger = new Logger();
logger.Output = msg => Console.WriteLine(msg);
logger.Output = msg => Console.WriteLine($"{DateTime.Now}: {msg}");
logger.Debug("测试1");
Console.ReadKey();
}
}
public delegate void OutPutAction(string msg);
public class Logger
{
public OutPutAction Output;
public void Debug(string msg)
{
Output(msg);
}
}
从以上代码,我们通过" "运算符,我们能将多个委托对象链接对象链接到一个委托对象实例上,使其称为多路广播实例。在调用委托链时,被绑定到委托链中的每个委托都会被执行
从委托链中移除委托
既然能用 “ ” 运算符把委托链接到一个委托对象实例上,自然也能用 “-” 运算符将某个委托从委托链对象上移除。请看下面示例代码
代码语言:javascript复制class Program
{
static void Main(string[] args)
{
var logger = new Logger();
var myDelegate = new OutPutAction((msg) => Console.WriteLine(msg));
logger.Output = msg => Console.WriteLine($"{DateTime.Now}: {msg}");
logger.Output = myDelegate;
logger.Output -= myDelegate;
logger.Debug("测试1");
Console.ReadKey();
}
}
public delegate void OutPutAction(string msg);
public class Logger
{
public OutPutAction Output;
public void Debug(string msg)
{
Output(msg);
}
}
归纳总结
委托是很多特性的基础,比如“事件”都是建立在委托之上的,前期如果实在不能理解,也别去钻牛角尖。先尝试写一两个示例,会写会用,接着往后看吧
常见面试题
委托是什么
委托是一个密封类,可以看成是一个函数指针,与指针不同的是我们知道它的返回类型和参数类型。委托类可以包含对多个方法的引用
为什么要用委托
- 开启一个新线程
- 将方法作为参数传递
- 事件,点击按钮的时候根据绑定的方法去调用
.Net 默认的委托类型有哪些
- Func 委托类型
- Action 委托类型
- Predicate 委托类型
多播委托是什么
这个委托包含多个方法叫多播委托