Skip to content

Instantly share code, notes, and snippets.

@unarist
Last active August 29, 2015 14:21
Show Gist options
  • Save unarist/aa026f6a9fc6895d34f1 to your computer and use it in GitHub Desktop.
Save unarist/aa026f6a9fc6895d34f1 to your computer and use it in GitHub Desktop.
パターンマッチ的な何か
public static class MatchExt
{
public static MatchState<TResult> BeginMatch<TResult>(this object source)
{
return new MatchState<TResult>(source);
}
}
public struct MatchState<TResult>
{
private readonly object source;
private readonly Maybe<TResult> result;
public Maybe<TResult> Result { get { return result; } }
public MatchState(object source)
{
this.source = source;
this.result = new Maybe<TResult>();
}
public MatchState(object source, Maybe<TResult> result)
{
this.source = source;
this.result = result;
}
public MatchState<TResult> Match<T>(Func<T, TResult> selector)
{
if(!result.HasValue && source is T)
{
return new MatchState<TResult>(this.source, Maybe.Create(selector((T)source)));
} else {
return this;
}
}
}
(new object[] {1, "a", DateTime.Now}).Select(_ =>
_.BeginMatch<int>()
.Match<int>(__ => __)
.Match<string>(__ => __.Length)
.Result // Maybe<int>
);
/*
* Officeとかにありがちな object[] Selection (でもどのクラスも概ねwidth持ってる)みたいなのをまとめて扱いたかった。のだけど、
* この方法だと値設定に使えないし、同じプロパティ名繰り返し書くことになるし、いっそ複数の型でフィルタしてdynamic使った方が楽だった。
*/
(new object[] {
new Shape { Width = 100 },
new Image { Width = 100 },
new Text { Width = 100 }
}).Select(_ =>
_.BeginMatch<int>()
.Match<Shape>(__ => __.Width)
.Match<Image>(__ => __.Width)
.Match<Text>(__ => __.Width)
.Result // Maybe<int>
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment