delegateとevent
delegateとeventの関係はフィールドと属性の関係と似ている。
int MyProperty { get; set; }
event Action MyEvent { add { } remove { } }
delegate
class WeatherStation
{
public Action willRainDelegate;
}
class WalkMan
{
public WalkMan(WeatherStation ws)
{
ws.willRainDelegate += () =>
{
Console.WriteLine("Take umbrella");
};
}
}
class BikeMan
{
public BikeMan(WeatherStation ws)
{
ws.willRainDelegate += () =>
{
Console.WriteLine("Wear poncho");
};
}
}
class Program
{
static void Main(string[] args)
{
WeatherStation ws = new WeatherStation();
WalkMan a = new WalkMan(ws);
BikeMan b = new BikeMan(ws);
ws.willRainDelegate();
}
}
常用関数delegate
★行動
public delegate void Action() { }
public delegate void Action<in T>(T obj) in引数は16個まで
list.ForEach(Program.MyAction);
public static void MyAction(string obj)
{
Console.WriteLine(obj);
}
★判定
public delegate bool Predicate<in T>(T obj)
string result = list.Find(Program.MyPredicate);
public static bool MyPredicate(string obj)
{
return obj == "abc" ? true : false;
}
★変換
public delegate TOutput Converter<in TInput, out TOutput>(TInput input)
List<int> intList = list.ConvertAll<int>(Program.MyConverter);
public static int MyConverter(string input)
{
int result;
if (!int.TryParse(input, out result))
{
result = -1;
}
return result;
}
★比較
public delegate int Comparison<in T>(T x, T y);
intList.Sort(Program.MyComparison);
public static int MyComparison(int x, int y)
{
return x.CompareTo(y);
}
★汎用
public delegate TResult Func<out TResult>();
public delegate TResult Func<in T, out TResult>(T arg); in引数は16個まで
event
class WeatherStation
{
public event Action willRainEvent;
public void WillRain()
{
willRainEvent();
}
}
class WalkMan
{
public WalkMan(WeatherStation ws)
{
ws.willRainEvent += () =>
{
Console.WriteLine("Take umbrella");
};
}
}
class BikeMan
{
public BikeMan(WeatherStation ws)
{
ws.willRainEvent += () =>
{
Console.WriteLine("Wear poncho");
};
}
}
class Program
{
static void Main(string[] args)
{
WeatherStation ws = new WeatherStation();
WalkMan a = new WalkMan(ws);
BikeMan b = new BikeMan(ws);
//ws.willRainEvent(); ×
ws.WillRain();
}
}
★C#のeventの標準モデル
class CustomEventArgs : EventArgs
{
public int Progress { get; set; }
}
class Publisher
{
public event EventHandler<CustomEventArgs> CustonEvent;
public void DoSomething()
{
var e = new CustomEventArgs() { Progress = 10 };
while (e.Progress > 0)
{
e.Progress--;
if (this.CustonEvent != null)
{
this.CustonEvent(this, e);
}
}
}
public void DoSomething(CustomEventArgs e)
{
while (e.Progress > 0)
{
//省略
}
}
}
//利用側
Publisher pub = new Publisher();
pub.CustonEvent += (sender, e) => { Console.WriteLine(e.Progress); };
pub.DoSomething();
class Subscriber
{
public Subscriber(Publisher pub)
{
pub.CustonEvent += this.Handle;
}
public void Handle(object sender, CustomEventArgs e)
{
//do something
}
}
//利用側
Publisher pub = new Publisher();
Subscriber sub = new Subscriber(pub);
pub.DoSomething();