はじめに

C#はRxやLINQをキメてる時はとても楽しいですが、Nullチェックをするのはとてもつらいです。

Nullableはオブジェクトに対して適用できないしインターフェースがあんまり好きじゃない...

C#8からnull参照型が実装されるらしいので今後は不要になるかもしれませんが、ScalaやSwiftでおなじみのOptionを実装してみました。
https://blogs.msdn.microsoft.com/dotnet/2017/11/15/nullable-reference-types-in-csharp/

コードはこちらになります。

https://github.com/seijiro/Option

尚パフォーマンスについては一切考えていません。

Optionを使うとどう嬉しいかは既に語り尽くされてると思うので下記の記事とか読んでみてください。

http://yuroyoro.hatenablog.com/entry/20100719/1279519961

使用例

生成

基本的にファクトリから生成します。


var some = Option<Int>.Some(100) // Some(100)
var none = Option<Int>.None() // None


https://github.com/seijiro/Option/blob/master/Option.cs#L254

Map

LINQで言うSelect


var some = Option<Int>.Some(100) // Some(100)
some.Map(number => number * 2) // Some(200)

https://github.com/seijiro/Option/blob/master/Option.cs#L194

FlatMap

LINQで言うSelectMany


var some = Option<Int>.Some(100) // Some(100)
some.FlatMap(number => Option<string>.Some(number.ToString())); // Some("100")


https://github.com/seijiro/Option/blob/master/Option.cs#L203

Filter

LINQで言う Where


var some = Option<Int>.Some(1) // Some(1)
some.Filter(num => num % 0 == 1) // Some(1)
some.Filter(num => num % 0 == 0) // None

https://github.com/seijiro/Option/blob/master/Option.cs#L214

GetOrElse

Optionからデータを取り出したいときに極力Unwrapは行いたくないと思います。

Scalaでは getOrElse/ Swiftでは ?? に相当するような関数はとても便利ですね。


// 偶数じゃなかった場合 -10000 を返す
var some = Option<Int>.Some(1) // Some(1)
var result = some.Filter(num => num % 0 == 0).GetOrElse(-10000) // -10000

Match

中が入っている場合はSome/ない場合はnoneがコールバックされます。


var some = Option<Int>.Some(1) // Some(1)

some.Match(
    some: value => // someのとき呼ばれる
    none: () => // none のときよばれる
)

https://github.com/seijiro/Option/blob/master/Option.cs#L157

AsOpt

以前の案件では as でキャストした直後にnullチェックするようなコードは結構な頻度で転がってました。

最近の言語では失敗した場合にOptionのNoneが戻る言語の方が多い気がするので実装しました。


var opt = Option<String>.AsOpt(100)

opt.Match(
    some: value => // 成功したら Some
    none: () => // 失敗したら None
)

おわり

頻繁に使うのはこの辺でしょうか。

この何番煎じかわからんネタで本当に需要があるのか気になる所ですが何か参考にしていただけるとうれしいです。

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.