忍者ブログ
おそらく活動状況とか、他愛もないこととか書きます。 μ崎みのりの気ままで気まぐれなブログです。 作曲とか、ゲーム製作なんかしてます。
[577]  [576]  [575]  [574]  [573]  [572]  [571]  [570]  [569]  [568]  [567
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

多くのプログラマを悩ませるnullに関する問題。
.NETだと、値型にはnull許容型が導入されたものの、参照型にはnull非許容型が導入されませんでした。
今から変更すると互換性等の問題が大きそうなので仕方ないでしょうが…。

……というわけで、疑似的にnull非許容の参照型を作ってみました。

public struct Safe<T> where T : class
{
    readonly T value;
    private Safe(T value)
    {
        this.value = value;
    }
    public static implicit operator Safe<T>(T value)
    {
        if (value == null) throw new ArgumentNullException("value");
        return new Safe<T>(value);
    }
    public static implicit operator T(Safe<T> safe)
    {
        if (safe.value == null) throw new InvalidOperationException("Safe<T>構造体に値が格納されていません。");
        return safe.value;
    }
}


いや、単純に構造体でラップしただけなのですが…。
元の型との間に暗黙の変換があり、変換時にnullをはじき出す、という単純な実装です。
メソッドの引数にstringじゃなくてSafe<string>を指定すれば、構造体がnullを許容しないから
nullを渡そうとした場合にIDEに指摘されるはず!!

……と思ったら指摘されませんでした。

ちゃんと暗黙の変換が働いたようです。スバラシイネー(白目)
というわけで、どちらにせよ実行時に例外が起きることでしか発見できない残念な仕様に。
しかもこれ、裏技を使うことでnullを例外を起こさずに代入できてしまうんです。

var safeStr = default(Safe<string>);

たったこれだけのコードで(このために、値を取り出す変換時もnullチェックが入ってます)。
なんだよ、意味ないじゃん…。

ただ、このSafe構造体が全くの無意味かというとそうでもないんですよね。
何よりも、引数の型として使うことでnull非許容であることを使用者にアピールできます。
また、(前述の裏技を除いて)引数として渡された時点でnullでないことが確定しているため、
ArgumentNullExceptionを毎回書く必要がなくなります。

で、ふいに思ったんですが、
この構造体にちょっとCLIのサポートがあれば完全にnull非許容な参照型が表せるんじゃないでしょうか?
具体的には、nullからSafe<T>への暗黙の変換を禁止したり、default(Safe<T>)を禁止したり…。
あ、ジェネリックを考えるとdefaultの禁止は難しいかな……。

そりゃ言語開発チームが難しいって言ってるんだから私が解決できるわけないですよね。

ただ、引数のnull禁止に関しては属性を使えばなんとかなると思うんです。
毎回書くのは面倒でしょうから、糖衣構文なんかを導入して。

void MyMethod(string! str) { ... }

こんな感じで型名の後に「!」をつけてnull非許容を表すことぐらいならできるんじゃないでしょうか。
どうにかならないですか、言語開発チームさん!!
PR
この記事にコメントする
お名前
タイトル
文字色
メールアドレス
URL
コメント
パスワード   Vodafone絵文字 i-mode絵文字 Ezweb絵文字
忍者ブログ [PR]