NULLの判定 その1
はじめに
サンプルプログラムではなく実際に使うプログラムを記述していくとnullのチェックがどうしても必要になりますよね。
初心者のうちは何をnull判定すべきで何をnull判定すべきではないか、どのメソッドにそれを実装すべきなのかなど、いろいろ悩むところだらけになりますよね。少なくとも私はそうでした。
ここではその話ではなくJavaにあるコンテナクラスでC#にもあったらいいなと思ったOptionalを実際に実装しようと思います。
必要な知識は、C#の初歩の部分と、このブログで前に話したラムダ式くらいがあれば自分で実装できると思います。
その前に当たり前のnull判定
Optionalの前に普通のnull判定を書いてみます。
public void DoSomething(string s) { if (s == null) { Console.WriteLine("nullですよ。"); } else { Console.WriteLine(string.Format("{0}ですよ。", s)); } }
なんだかんだあるかもしれませんが、こうなることがほどんどだと思います。
JavaのOptional
JavaSEのドキュメントを見ると値を1つ保持ことができるコンテナオブジェクトで、値がnullじゃないときに動作させる関数、値がnullじゃないときに動作させる関数が用意されているようです。
目的はnullを許容する値をコンテナに入れてコンテナを介してアクセスすることで保守性や安全性を高めることに見えます。
これと同じような動きをC#で実現してみようと思います。
最新のC# 8.0はnullに関する機能強化がたくさんあるので必要ないかもですが、社内ではC#7.0系もしくは5.0系なのですよ。
作り出し
まず値を一つ持つコンテナクラスを実装します、クラス名はもちろんOptionalで。
class Optional<T> where T : class { private T value; public Optional(T value) { this.value = value; } }
はい、できました。
Optional<T>としたのでジェネリックです。where以下はジェネリック型制約で T この場合 Tはclassであることとなります。nullを許容する値のコンテナなのでTはclassとしています。
補足ですが制約にclassではなくstructとするとnull非許容型に対するコンテナになります。今回の目的では意味がなくなりますので制約はあくまでclassです。
このコンテナにはコンストラクタが1つかつその引数がジェネリック引数T型となっています。
コンテナオブジェクトなので引数が無いコンストラクタでNEWと「何をコンテナするの?」ってなって意味がなくなりますので。
そしてコンテナをNewするとそのときの引数はプライベート変数に格納されて、外部からはアクセスできないようにしておきます。
次回
これで値にアクセスできないコンテナオブジェクトができたので、次回は値を提供するメソッドを作ってみます。