我正在阅读一篇文章,该文章通过以下示例描述了委托的使用 它显示了多播委托的使用
public delegate void ProgressReporter(int percentComplete);
class Program
{
static void Main(string[] args)
{
ProgressReporter p = WriteProgressToConsole;
p += WriteProgressToFile;
Utility.HardWork();
}
private static void WriteProgressToConsole(int percentComplete)
{
Console.WriteLine(percentComplete);
}
private static void WriteProgressToFile(int percentComplete)
{
System.IO.File.WriteAllText("progress.txt", percentComplete.ToString());
}
}
public static class Utility
{
public static void HardWork(ProgressReporter p)
{
for (int i = 0; i < 10; i++)
{
p(i);
System.Threading.Thread.Sleep(1000);
}
}
}
但是根据我对代码的理解,我认为可以使用类来完成同样的功能,并使用相同的函数来定义委托处理程序完成的任务,如下所示
public static class ProgressReporter
{
public static void WriteProgressToConsole(int percentComplete)
{
Console.WriteLine(percentComplete);
}
public static void WriteProgressToFile(int percentComplete)
{
System.IO.File.WriteAllText("progress.txt", percentComplete.ToString());
}
}
并按如下方式更改Utility类HardWork()
public static class Utility
{
public static void HardWork()
{
for (int i = 0; i < 10; i++)
{
ProgressReporter.WriteProgressToConsole(i * 10);
ProgressReporter.WriteProgressToFile(i * 10);
System.Threading.Thread.Sleep(1000);
}
}
}
所以我对这段代码的问题是,为什么我们实际上需要一个委托呢?
我认为我们需要委托的一些原因(如果我错了,则正确),如下所示 -
答案 0 :(得分:3)
委托是一种将特定方法作为变量引用的方法,这意味着它可以更改,而不是作为最后一个示例,硬编码到程序中调用哪些方法。
没有代表,有没有办法做到这一点?当然,您可以提供覆盖方法或使用实现接口的类的对象,但是代理在您不需要围绕单个方法的整个类型的意义上更便宜。
硬编码不起作用的情况示例,接口/覆盖方法比委托更多的工作,尝试查看可视组件及其事件。 .NET中的事件使用委托。您只需双击Visual Studio中可视化设计器中的按钮,它就会为您创建方法,并通过委托方式将其连接到事件。必须创建一个类,或者在表单类之上实现一个接口会有很多工作,特别是如果你有多个按钮要做不同的事情,那么你肯定需要多个对象来实现这些接口。 / p>
所以代表们有自己的位置,但是你的例子并不公平。
这是一个LINQPad示例,它演示了一种方法(DoSomething
)最终可以根据提供给它的委托执行不同的操作:
void Main()
{
DoSomething(msg => Console.WriteLine(msg));
using (var writer = new StreamWriter(@"d:\temp\test.txt"))
{
DoSomething(msg => writer.WriteLine(msg));
}
}
public delegate void LogDelegate(string message);
public static void DoSomething(LogDelegate logger)
{
logger("Starting");
for (int index = 0; index < 10; index++)
logger("Processing element #" + index);
logger("Finishing");
}
这将首先登录到控制台,然后重新运行该方法并登录到文件。
答案 1 :(得分:0)
在下列情况下使用代理人 1.使用事件设计模式(事件处理程序) 2.一个类可能需要多个方法的实现 3.Thread实现(Thread Start,sleep etc)
了解更多信息 https://msdn.microsoft.com/en-us/library/ms173173.aspx: