イベントをデリゲート型のインスタンスと見なすことの副作用は何ですか?
Jon Skeet は、「イベントはデリゲート インスタンスではありません」と述べています。. もし私がこれを他の場所で読んでいたら、私はこれを尋ねなかったでしょう。
過去 2 か月間、私は常にイベントを特別なタイプのデリゲートとして視覚化し、イベントキーワードを使用して、イベントを介して呼び出されるデリゲートの無効化を防止していました。
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 に記事を書きました。