の呼び出しで警告が表示される理由はないことに注意してくださいConsole.WriteLine()
。参照型プロパティはnull許容型ではないため、nullである可能性があることをコンパイラが警告する必要はありません。
コンパイラーstruct
自体の参照についてコンパイラーが警告する必要があると主張するかもしれません。それは私には理にかなっているようです。しかし、そうではありません。これは、値型のデフォルトの初期化によって引き起こされる抜け穴のようです。つまり、常にすべてのフィールド(参照型フィールドの場合はnull、数値型の場合はゼロなど)を常にゼロにするデフォルト(パラメーターなし)コンストラクターが必要です。 )。
私はそれを抜け穴と呼びます。理論的には、null不可の参照値は実際には常にnull以外であるべきだからです。ああ。:)
この抜け穴は、このブログ記事「C#でのnull可能な参照型の紹介」で対処されているようです。
nullの回避これまでのところ、警告はnull可能な参照のnullが逆参照されないように保護することに関するものでした。コインの反対側は、null不可の参照にnullがまったく含まれないようにすることです。
null値が存在する可能性のある方法はいくつかあり、それらのほとんどは警告する価値がありますが、それらのうちのいくつかは、回避する方が良い別の「警告の海」を引き起こす可能性があり
ます。
- nullを許容しない参照型のフィールドを持つ構造体のデフォルトのコンストラクターを使用する。デフォルトのコンストラクター(構造体をゼロにする)は暗黙的に多くの場所で使用できるため、これは卑劣です。おそらく警告しない方がいいでしょう [強調マイン-PD]。さもなければ、多くの既存の構造体タイプは役に立たなくなるでしょう。
つまり、これは抜け穴ですが、バグではありません。言語設計者はそれを認識していますが、このシナリオを警告から除外することを選択しました。struct
初期化が機能です。
これは、この機能の背後にあるより広範な哲学と一致していることに注意してください。同じ記事から:
したがって、既存のコードについて文句を言う必要があります。しかし、不愉快なことではありません。ここでは、そのバランスをとる方法を説明します。
…
- すべての警告に反応して排除したとしても、ヌルの安全性は保証されません[強調-PD]。分析には必要に応じて多くの穴があり、一部は選択による穴もあります。
その最後のポイントまで:時には警告は「正しい」ことですが、実際にnullセーフな方法で書かれている場合でも、既存のコードでは常に発生します。そのような場合、正確さではなく、利便性の面で誤りを犯します。既存のコードで「警告の海」を生み出すことはできません。あまりに多くの人々が警告をオフにして、それから利益を得ることは決してありません。
また、この同じ問題が、名目上nullにできない参照型の配列(たとえばstring[]
)にも存在することに注意してください。配列を作成すると、すべての参照値はnull
、これは正当であり、警告は生成されません。
なぜ物事が現状のままであるのかを説明するためにこれで終わりです。次に、問題はどうなりますか?それはもっと主観的です、そして私は正しいか間違った答えがあるとは思いません。つまり…
私は個人的にstruct
ケースバイケースでタイプを扱います。意図するところのために実際にNULL可能参照型ですが、私は適用される?
注釈を。そうでなければ、私はしません。
技術的には、aのすべての参照値はstruct
「null可能」である必要があります。つまり?
、型名にnull可能注釈を含めます。しかし、多くの同様の機能と同様に(C#での非同期/待機など)const
C ++、これは「感染性」の側面があり、後でそのアノテーションをオーバーライドする!
か、明示的なnullチェックを含める必要があります。、またはその値をnull可能な別の参照型変数に割り当てるだけです。
私にとって、これは、null許容の参照型を有効にする多くの目的を無効にします。そのようなstruct
型のメンバーはいずれにせよ特別な場合の処理を必要とし、null不可の参照型を引き続き使用しながら本当に安全に処理する唯一の方法はstruct
、を使用するすべての場所にnullチェックを配置することであるため、コードがを初期化するときstruct
、それを正しく行い、null不可の参照型メンバーが実際にnull以外の値に初期化されるようにするのはコードの責任であるということを受け入れるのは、妥当な実装選択です。
これは、デフォルト以外のコンストラクタ(つまり、パラメータを持つコンストラクタ)やファクトリメソッドなどの初期化の「公式な」手段を提供することで支援できます。デフォルトのコンストラクタを使用するリスクは常に存在しますが、配列の割り当てのようにコンストラクタをまったく使用しないリスクがありますが、struct
正しく、これを使用するコードが非null可能な変数。
つまり、null許容の参照型に関する100%の安全性が必要な場合は、その特定の目標に対する正しいアプローチは、常に、struct
with 内のすべての参照型メンバーに注釈を付けること?
です。これは、すべてのフィールドとすべての自動実装プロパティ、およびそのような値またはそのような値の積を直接返すメソッドまたはプロパティゲッターを意味します。次に、使用するコードには、そのような値がnullを許容しない変数にコピーされるすべてのポイントにnullチェックまたはnullを許容する演算子を含める必要があります。