5

.NET での null 非許容参照型のサポートに関して、多くの質問がありました。コード コントラクトが大いに期待されていましたが、予算が限られている人向けの実行時チェックに限定されています。

コード コントラクト以外のアプローチについては、Jon Skeet が数年前にこれに関するブログ記事を書きました。コメント投稿者の 1 人が、デフォルト コンストラクターを無効にするように IL を変更した便利な見た目のNonNull 構造体を提供しました。これは優れたアプローチのように思えます。これを拡張して、あらゆる種類の null 非許容のmicrotypesを提供することを想像できます。IL 操作は、構造体の属性によってトリガーされるビルド後のステップである可能性があります。

//Microtype representing a non-zero age, so we want to disable the default ctor
[NoDefaultConstructor]
public struct Age
{
    public Age(int age)
    {
        // Implementation (including validation) elided
    }
} 

これをさらに調査する前に、これが引き起こす可能性のある問題を誰かが知っているかどうか尋ねたいと思いますか? 私は何も考えることができませんでした。

4

1 に答える 1

6

これは非常に簡単に無効にすることができます - ランタイムは、すべてのシナリオで (存在する場合) 構造体のパラメーターなしのコンストラクターを呼び出そうとしません。

特に、構造体型の配列を作成するときは呼び出されません。

Age[] ages = new Age[3];

// This guy skips your "real" ctor as well as the "invalid" parameterless one.
Age age = ages[0];

...またはdefault(structType)式で:

// Invalid state here too.
Age age = default(Age);

このことに関するJon Skeet の経験的研究から、コンストラクターを呼び出さない他の操作のリストを次に示します。

  • ローカル、静的、インスタンスのいずれであっても、変数を宣言するだけです
  • ボクシング
  • default(T)ジェネリック メソッドでの使用
  • new T()ジェネリック メソッドでの使用

ここで、インスタンスがフェンスを回避して作成されたかどうかを何らかの方法でテストする必要があるという状況に陥ります。Ageこれは、最初にフェンスを構築しなかったことよりもはるかに良いことではありません。

于 2011-10-10T13:22:30.617 に答える