将事件视为委托类型的实例有什么副作用?
Jon Skeet 说,“事件不是委托实例。”,在这里。. 如果我在其他任何地方读过这篇文章,我就不会问这个。
在过去的 2 个月里,我一直将事件可视化为特殊类型的委托,使用event关键字只是帮助防止通过事件调用的委托无效。
有人可以详细说明如何为 C# 和基于事件的编程新手正确地可视化整个概念吗?
编辑1:
我理解了代表的概念,因此事件被证明是一个非常简单的概念。我想继续添加一个我在与这些构造物的战斗中变出的例子。我添加了很多评论以便更好地理解。这适用于像我这样的新人:
库 DLL:
namespace DoSomethingLibrary
{
/*
*This is a public delegate declared at the base namespace level for global presence.
*The question is WHY do we need to have a DELEGATE here?
*The answer is: I do not want to implement the LOGGING logic. Why? Well, my consumers are many
*and all are equally demanding. They all need different types of logging. Some need HTML logging,
*some need XML logging for their custom log analyzer, some need plain text logging etc...
*This is hell for me. How am I going to support all their demands. I cannot. Thus, I ask them to
*implement LOGGING on their side. I am providing an INTERFACE(literal sense) in the guise of a DELEGATE.
*A DELEGATE is a HOOK.
*This is the hook that is needed for consumers to hook their custom loggers into the library.
*/
public delegate void Logger(string firstParam, string secondParam);
public class PrintingManiac
{
public Logger printingManiacConsumerLoggerHook;
public void StartPrintingLikeAManiac()
{
for (int iterator = 0; iterator <= 3; iterator++)
{
/*This loop is an emulator which I am using to emulate some huge processing or some huge job.
*Let us imagine that this is a library that does some heavy data crunching OR some
*extremely complex data access job etc..
*/
Console.WriteLine("Actual WORK - " + iterator.ToString());
/*After each step this library tries to LOG. But NOTE that this library
*has no LOGGER implemented. Instead, this library has judiciously DELEGATED
*the logging responsibilty to the CONSUMER of this library.
*/
printingManiacConsumerLoggerHook("Actual Work", "Step " + iterator.ToString());
}
}
}
}
消费者可执行文件:
/*
* Let us assume that I have purchased the DoSomethingLibrary DLL from a vendor.
* I have to add the DLL as a reference to my executable's project in Visual Studio.
* I also have to use the DoSomethingLibrary namespace to access the Logic in the DLL.
*/
using DoSomethingLibrary;
namespace UnderstandingDelegates
{
class Program
{
static void Main(string[] args)
{
/*
* Creating an object of the lone class PrintingManiac in the DoSomethingLibrary
*/
PrintingManiac newManiac = new PrintingManiac();
/*
* HOOKING my custom logger to the DoSomethingLibrary DLL.
* I get the best of both the worlds. I have a well-tested and efficient library working for me
* AND I have the best logging avaliable.
* The DoSomethingLibrary DLL has no knowledge of what logging this executable is going to use.
* This executable has to just satisfy the requirements of the DELEGATE signature of DoSomethingLibrary DLL.
*/
newManiac.printingManiacConsumerLoggerHook += new Logger(ClientsCustomizedLoggerTwo);
newManiac.StartPrintingLikeAManiac();
Console.ReadLine();
}
public static void ClientsCustomizedLoggerOne(string firstParam, string secondParam)
{
/*
*This logger has '=' used as a decorator
*In real scenarios the logger may be very complex.
*Let us assume this is an HTML logger
*/
Console.WriteLine("=============================");
Console.WriteLine("Delegated Logging IN CONSUMER code " + firstParam + " - " + secondParam);
Console.WriteLine("=============================");
}
public static void ClientsCustomizedLoggerTwo(string firstParam, string secondParam)
{
/*
*This logger has '-' used as a decorator
*Let us assume this is an XML logger
*/
Console.WriteLine("------------------------------");
Console.WriteLine("Delegated Logging IN CONSUMER code " + firstParam + " - " + secondParam);
Console.WriteLine("------------------------------");
}
}
}
编辑2:
我在 CodeProject中写了一篇文章,清楚地解释了代表的整个概念。