[C#Advanced]サードパーティライブラリイベントの動的登録、簡単に完了!詳細な手順と例。

[C#Advanced]サードパーティライブラリイベントの動的登録、簡単に完了!詳細な手順と例。

C#開発では、しばしばイベントを処理する必要があり、サードパーティライブラリが定義するイベントを動的に登録する必要があります。今日は、サードパーティ製のライブラリイベントを動的に登録する方法のデモを共有し、提供されたコードとコメントに基づいて各ステップを詳細に説明します。

最后更新 2024/02/03 22:57
沙漠尽头的狼
预计阅读 5 分钟
分类
.NET
标签
.NET C# イベント登録

こんにちは、私は砂漠の果ての狼です!

C#開発では、しばしばイベントを処理する必要があり、サードパーティライブラリが定義するイベントを動的に登録する必要があります。今日は、サードパーティ製のライブラリイベントを動的に登録する方法のデモを共有し、提供されたコードとコメントに基づいて各ステップを詳細に説明します。この記事を通じて、イベントを動的に登録する方法をよりよく理解し、開発作業により便利になることを願っています。

C#では、イベントはクラスやオブジェクトの状態の変化を通知する特別なメンバである。サードパーティ製ライブラリを使用する場合、イベントが発生したときにアクションを実行できるように、これらのライブラリで定義されたイベントを動的に登録する必要がある場合があります。

以下では、サードパーティライブラリイベントを動的に登録する方法をデモで示します。

I.準備作業

首先,我们需要一个第三方库的示例代码。在这个示例中,我们有一个名为ThirdLibrary的库,其中包含一个名为TestClass的类。这个类定义了几个事件和委托,我们将动态地为它们添加处理程序。

namespace ThirdLibrary;

public class TestClass
{
    /// <summary>
    /// 无参委托
    /// </summary>
    public Action? NoParamEvent;

    /// <summary>
    /// 带1个string参数
    /// </summary>
    public Action<string>? OneParamEvent;

    /// <summary>
    /// 带1个基本类型和自定义类型的委托
    /// </summary>
    public Action<string, EventParam>? TwoParamEvent;

    /// <summary>
    /// EventHandler事件
    /// </summary>
    public static event EventHandler<EventParam> EventHandlerEvent;

    public void CallEvent()
    {
        NoParamEvent?.Invoke();
        OneParamEvent?.Invoke("单参数委托");
        TwoParamEvent?.Invoke("2个参数委托调用成功", new EventParam() { Message = "帅哥,你成功调用啦!" });
        EventHandlerEvent?.Invoke(this, new EventParam { Message = "EventHandler事件调用成功"});
    }
}

/// <summary>
/// 自定义类型,注册时需要使用dynamic接收
/// </summary>
public class EventParam
{
    public string Message { get; set; }
}

サードパーティ製ライブラリの読み込みとインスタンスの作成

首先,我们使用Assembly.LoadFrom方法加载第三方库。然后,通过Assembly.GetType方法获取TestClass的类型,并使用Activator.CreateInstance方法创建其实例。

using System.Reflection;

// 加载第三方库  
var assembly = Assembly.LoadFrom("ThirdLibrary.dll");

// 创建TestClass的实例  
var testClassType = assembly.GetType("ThirdLibrary.TestClass");
var testClassInstance = Activator.CreateInstance(testClassType!);

3.ダイナミック登録イベント

接下来,我们将通过反射动态地注册事件。首先,通过Type.GetFields方法获取TestClass类型的所有字段,并找到对应的事件字段。

var fields = testClassType!.GetFields();
  1. 引数のない委任イベントの

通过字段名称找到NoParamEvent字段,并使用FieldInfo.SetValue方法将事件处理程序方法EventHandlerMethod赋值给该字段。这样,当NoParamEvent事件被触发时,EventHandlerMethod方法将被调用。

// 1、获取NoParamEvent委托  
var noParamEventField = fields.First(field => "NoParamEvent" == field.Name);
noParamEventField.SetValue(testClassInstance, EventHandlerMethod);

// NoParamEvent事件处理程序方法  
void EventHandlerMethod()
{
    Console.WriteLine("NoParamEvent: event raised.");
}
  1. 1つの文字列引数で委任イベントをする

类似地,找到OneParamEvent字段,并将其设置为OneParamEventHandler方法。这个方法接受一个字符串参数,并打印一条消息。

// 2、获取OneParamEvent委托,并设置事件参数处理程序  
var oneParamEventField = fields.First(field => "OneParamEvent" == field.Name);
oneParamEventField.SetValue(testClassInstance, OneParamEventHandler);

// OneParamEvent事件处理程序方法,需要一个字符串参数  
void OneParamEventHandler(string param)
{
    Console.WriteLine($"OneParamEvent: event raised with parameter: {param}");
}
  1. 2つの引数で委任イベントを

对于TwoParamEvent字段,我们将其设置为TwoParamEventHandler方法。由于第二个参数是自定义类型EventParam,我们无法在编译时知道其确切类型。因此,我们使用dynamic关键字作为参数类型,以便在运行时解析类型。

// 3、获取TwoParamEvent委托,并设置事件参数处理程序  
var twoParamEventField = fields.First(field => "TwoParamEvent" == field.Name);
twoParamEventField.SetValue(testClassInstance, TwoParamEventHandler);

// TwoParamEvent事件处理程序方法,需要两个参数:string和EventParam类型(通过反射传递,EventParam类型使用动态类型dynamic替换)  
void TwoParamEventHandler(string param1, dynamic param2) // 使用dynamic作为第二个参数的类型,并通过反射传递实际参数值  
{
    Console.WriteLine($"TwoParamEvent: event raised, param1={param1}, param2.Param1={param2.Message}");
}
  1. EventHandlerイベントの登録

对于EventHandlerEvent事件,我们使用Type.GetEvents方法获取事件信息,并通过EventInfo.EventHandlerType获取事件处理程序的类型。然后,我们创建一个EventHandler<dynamic>类型的委托,并使用Delegate.CreateDelegate方法创建一个与事件处理程序类型匹配的委托实例。最后,通过EventInfo.AddEventHandler方法将委托实例添加到事件中。

var events = testClassType.GetEvents();

// 4、获取EventHandler事件
var eventHandlerEventField = events.First(item => "EventHandlerEvent" == item.Name);
var eventHandlerType = eventHandlerEventField.EventHandlerType;
var eventHandlerMethod = new EventHandler<dynamic>(EventHandlerEventHandler);
var handle = Delegate.CreateDelegate(eventHandlerType, eventHandlerMethod.Method);
eventHandlerEventField.AddEventHandler(null, handle);

// EventHandler事件处理方法
void EventHandlerEventHandler(object sender, dynamic param)
{
    Console.WriteLine($"EventHandler: param.Param1={param.Message}");
}

IV.イベントのトリガーと登録の検証

为了验证事件是否成功注册,我们调用TestClassCallEvent方法,该方法将触发所有已注册的事件。如果一切正常,我们将在控制台上看到相应的输出消息,证明事件处理程序被正确调用。

ThirdLibraryライブラリのメソッド

/// <summary>
/// 该方法用于触发事件,方便测试
/// </summary>
public void CallEvent()
{
    NoParamEvent?.Invoke();
    OneParamEvent?.Invoke("单参数委托");
    TwoParamEvent?.Invoke("2个参数委托调用成功", new EventParam() { Message = "帅哥,你成功调用啦!" });
    EventHandlerEvent?.Invoke(this, new EventParam { Message = "EventHandler事件调用成功" });
}

上記のイベントのトリガー:

// 5、模拟触发事件通知,测试事件是否注册成功
var callEventMethod = testClassType.GetMethods().First(method => "CallEvent" == method.Name);
callEventMethod.Invoke(testClassInstance, null);

プログラムの出力は以下の通り。

NoParamEvent: event raised.
OneParamEvent: event raised with parameter: 单参数委托
TwoParamEvent: event raised, param1=2个参数委托调用成功, param2.Param1=帅哥,你成功调用啦!
EventHandler: param.Param1=EventHandler事件调用成功

V.サマリー

以上の手順により、サードパーティライブラリ定義イベントの動的登録に成功しました。このアプローチは、実行時にイベントハンドラを動的に追加または削除できるため、予測不可能または変更不可能なサードパーティ製ライブラリを扱う場合に便利です。

この記事が、サードパーティライブラリイベントを動的に登録し、実際の開発で柔軟に適用する方法を理解するのに役立つことを願っています。ご質問やご提案がある場合は、お気軽にメッセージ交換!

Keep Exploring

延伸阅读

更多文章
同分类 / 同标签 2026/04/22

バージョン別の. NETサポート状況(250 7 0 7更新)

仮想マシンとテストマシンを使用して、各バージョンのオペレーティングシステムの. NETサポートをテストします。オペレーティングシステムのインストール後、対応するランタイムを測定し、スターダストエージェントをパスとして実行できます。

继续阅读
同分类 / 同标签 2026/02/07

AOTの使用経験

プロジェクトの最初から、新しい機能が追加されたり、新しい構文が使用されたりするたびに、AOTリリーステストを行うという良い習慣を身につける必要があります。

继续阅读