イベント引数EventArgsにカスタム値を持たせるようにします。
もし認識が誤りがあれば、ご指摘をお願いします。
12/22 ちょこっと変えてみました。
12/27 ちょこっと変えてみました。ご指摘のあった部分を改良しました。
基底クラス系のクラス名AtepからはじまるAtep とは、新たに発見した万能 細胞 関数 Arbitary-Triggered Eventhandler of Pluripotencyの略です。Stupid-Triggered EventArgs of PluripotencyでStep でもいいかなと考えました。いっそのこと、Stimulus-Triggered Actions of PluripotencyでStapってのはどうでしょうか。
要するにEventArgsを型引数クラスで継承して万能 細胞 関数化してるってことなんですよ。
次回は、この応用でランチャにタスクを実装した方式を掲載ます。
#本文
##基底関数群
public class AtepEventArgs<T> : EventArgs
{
public T Value { get; private set; }
public AtepEventArgs(T val)
{
Value = val;
}
}
public delegate void EventHandler<TSender, TEventArgs>(TSender sender, TEventArgs e);
public interface ILauncher<T>
{
event EventHandler<object, AtepEventArgs<T>> Raise;
}
public class AtepLauncher<T> : ILauncher<T>
{
private T arg = default(T);
public AtepLauncher()
{
}
public AtepLauncher(T a)
{
this.arg = a;
}
public T Arg
{
get
{
return this.arg;
}
set
{
this.arg = value;
OnChanged(this, new AtepEventArgs<T>(this.arg));
}
}
// Delegate
public event EventHandler<object, AtepEventArgs<T>> Raise;
// Trigger
public void OnChanged(object sender, AtepEventArgs<T> e)
{
if (Raise != null)
{
// Call the Event
Raise(this, e);
}
}
}
public class AtepContainer<T>
{
private List<ILauncher<T>> launcher;
public AtepContainer()
{
this.launcher = new List<ILauncher<T>>();
}
public void Add(ILauncher<T> lchr)
{
lchr.Raise += new EventHandler<object, AtepEventArgs<T>>(HandleChanged);
this.launcher.Add(lchr);
}
internal virtual void HandleChanged(object sender, AtepEventArgs<T> e)
{
// イベント発火, ここにoverride メソッドを記述
Console.WriteLine("Received event. value={0}", e.Value);
}
}
##目的別の関数
/// <summary>
/// (目的の)型
/// </summary>
public class MyItem
{
public MyItem()
{
}
public MyItem(int n, string s)
{
Number = n;
TextMessage = s;
}
public int Number { get; set; }
public string TextMessage { get; set; }
}
/// <summary>
/// (目的の)メイン
/// </summary>
internal class Test
{
private static Test _instance { get; set; }
public static Test GetInstance()
{
return _instance;
}
private static void Main(string[] args)
{
var myLauncher = new AtepLauncher<MyItem>();
var container = new MyContainer();
container.Add(myLauncher);
myLauncher.Arg = new MyItem(1, "Item1");
// Keep the console window open in debug mode.
System.Console.WriteLine("Press any key to exit.");
System.Console.ReadKey();
}
}
##コード全体
using System;
using System.Collections.Generic;
using System.Threading;
/// <summary>
/// Note :
/// Atep = Arbitary-Triggered Eventhandler of Pluripotency
/// </summary>
namespace RaiseBaseClassEventsTestPart3
{
public class AtepEventArgs<T> : EventArgs
{
public T Value { get; private set; }
public AtepEventArgs(T val)
{
Value = val;
}
}
public delegate void EventHandler<TSender, TEventArgs>(TSender sender, TEventArgs e);
public interface ILauncher<T>
{
event EventHandler<object, AtepEventArgs<T>> Raise;
}
public class AtepLauncher<T> : ILauncher<T>
{
private T arg = default(T);
public AtepLauncher()
{
}
public AtepLauncher(T a)
{
this.arg = a;
}
public T Arg
{
get
{
return this.arg;
}
set
{
this.arg = value;
OnChanged(this, new AtepEventArgs<T>(this.arg));
}
}
// Delegate
public event EventHandler<object, AtepEventArgs<T>> Raise;
// Trigger
public void OnChanged(object sender, AtepEventArgs<T> e)
{
if (Raise != null)
{
// Call the Event
Raise(this, e);
}
}
}
public class AtepContainer<T>
{
private List<ILauncher<T>> launcher;
public AtepContainer()
{
this.launcher = new List<ILauncher<T>>();
}
public void Add(ILauncher<T> lchr)
{
lchr.Raise += new EventHandler<object, AtepEventArgs<T>>(HandleChanged);
this.launcher.Add(lchr);
}
internal virtual void HandleChanged(object sender, AtepEventArgs<T> e)
{
// イベント発火, ここにoverride メソッドを記述
Console.WriteLine("Received event. value={0}", e.Value);
}
}
/// <summary>
/// (目的の) ランチャコンテナ
/// </summary>
public class MyContainer : AtepContainer<MyItem>
{
internal override void HandleChanged(object sender, AtepEventArgs<MyItem> e)
{
if (e.Value == null)
return;
var item = e.Value as MyItem;
var s = string.Format("({0}, {1})", item.Number.ToString(), item.TextMessage);
Console.WriteLine("Received event." + s);
}
}
/// <summary>
/// (目的の)型
/// </summary>
public class MyItem
{
public MyItem()
{
}
public MyItem(int n, string s)
{
Number = n;
TextMessage = s;
}
public int Number { get; set; }
public string TextMessage { get; set; }
}
/// <summary>
/// (目的の)メイン
/// </summary>
internal class Test
{
private static Test _instance { get; set; }
public static Test GetInstance()
{
return _instance;
}
private static void Main(string[] args)
{
var myLauncher = new AtepLauncher<MyItem>();
var container = new MyContainer();
container.Add(myLauncher);
myLauncher.Arg = new MyItem(1, "Item1");
// Keep the console window open in debug mode.
System.Console.WriteLine("Press any key to exit.");
System.Console.ReadKey();
}
}
}
#参考
-
方法 : 派生クラスから基本クラス イベントを発生させる (C# プログラミング ガイド)
https://docs.microsoft.com/ja-jp/dotnet/csharp/programming-guide/events/how-to-raise-base-class-events-in-derived-classes -
方法: .NET Framework ガイドラインに準拠したイベントを発行する (C# プログラミング ガイド) https://docs.microsoft.com/ja-jp/dotnet/csharp/programming-guide/events/how-to-publish-events-that-conform-to-net-framework-guidelines
-
方法 : クラスにイベントを実装する
https://msdn.microsoft.com/ja-jp/library/5z57dxz2(v=vs.110).aspx