2009-05-06 10 views
35

私はこの概念が.net 2.0で導入されて以来、これに関するいくつかの良い指針を探してきました。なぜ私はいつもCでヌル入力可能な型を使うべきではない

なぜNULLを使用できないデータ型をC#で使用したいのですか? (より良い質問は、デフォルトでnull可能な型を選択し、それが明示的に意味があるときにnullable型を使用しない理由です)。ヌル可能ピア?

私は、Guid.empty、string.empty、DateTime.MinValue、< = 0などの代わりにnullに対して自分の値をチェックし、一般的にnull可能な型を扱う方が好きです。私がnullableタイプをもっと頻繁に選んでいない唯一の理由は、私の頭の後ろにあるかゆみのような感覚です。文字を使用して、NULL値を明示的に許可します。

常に(ほとんどの場合)nullable型ではなくnullable型を選択する人がいますか?お時間を

おかげで、

+0

Jon Skeetは構造体であるSystem.Nullableについては正しいです。したがって、ヒープではなくスタックに割り当てられます。 –

+3

パフォーマンスヒットに関する質問は、あなただけが回答できます。あなたはあなたの顧客にとって何が「重要」であるかを知っている人です。しかしヒットは最小限でなければなりません。null可能なintは、intとそれがnullかどうかを示すboolフラグと全く同じです。 Nullable 型はintをフラグでパッケージ化するのに便利な方法です。 –

答えて

46

理由は、時にはあなたが値初期化されることを保証することが可能だということです。また、できるだけ頻繁にコードを設計するようにしてください。値が初期化されていない可能性がない場合は、nullが正当な値でなければならない理由はありません。非常に簡単な例として、このことを考慮してください。

List<int> list = new List<int>() 
int c = list.Count; 

これは常に有効です。 cを初期化できない可能性はありません。 int?に変更された場合は、コードの読者に「この値はnullである可能性があります。使用する前に必ず確認してください」というメッセージが表示されます。しかし、これは決して起こり得ないことを知っています。なぜこの保証をコードに公開しないのですか?

値がオプションの場合は絶対に正しいです。文字列を返すこともあれば返すこともできない関数がある場合は、nullを返します。 string.Empty()を返さないでください。 「魔法の値」を返さないでください。

ただし、すべての値がオプションであるとは限りません。オプションのすべてをオプションにすると、コードの残りの部分がはるかに複雑になります(別のコードパスを追加する必要があります)。

この値が常に有効であることが特に保証できれば、なぜこの情報を捨てるのですか?それはあなたがnullable型にすることによってそれをします。値が存在する場合と存在しない場合があり、値を使用する人はどちらの場合も処理する必要があります。しかし、あなたは、これらのケースのうちの1つだけが最初に可能であることを知っています。したがって、コードのユーザーは好意的に行動し、この事実をコードに反映させることができます。コードのすべてのユーザーは、有効な値に依存することができ、2つではなく1つのケースを処理するだけで済みます。

+0

これは本当に良い答えですが、それを修正したいのです。エンタープライズアプリケーションのBussiness Domain Class Propertiesに常にNullable型を使用しないでください。それは私がおそらくほとんどの時間できると思う。御時間ありがとうございます。 –

+2

私は親指の同じルールがそこに適用されると思います。プロパティが常に有効であることを保証できますか? (あなたのオブジェクトはおそらくIDを持っているので、そのnullableを作ることはできませんが、オブジェクトの状態によっては他のプロパティが存在する場合と存在しない場合がありますが、* null *それは、ユーザーがnullに対してそれをチェックする必要がないので、将来的にはもっとうまくいくようになります。プロパティが有効であることを保証することが可能かどうかを確認してください。 – jalf

+5

参照型をnull以外の型として宣言するためにSpec#フィーチャを取得した場合、クールではないでしょうか? 'string!'はnullにすることのできない文字列を表します。 –

9

それは常にNULL可能タイプがnullあるかどうかを確認する必要が不便だからです。

明らかに、値が真にオプションであり、そのような場合は、マジックナンバーなどではなくヌル可能な型を使用するのが理にかなっていますが、可能であれば、それらを回避しようとします。

// nice and simple, this will always work 
int a = myInt; 

// compiler won't let you do this 
int b = myNullableInt; 

// compiler allows these, but causes runtime error if myNullableInt is null 
int c = (int)myNullableInt; 
int d = myNullableInt.Value;  

// instead you need to do something like these, cumbersome and less readable 
int e = myNullableInt ?? defaultValue; 
int f = myNullableInt.HasValue ? myNullableInt : GetValueFromSomewhere(); 
+0

私はこれが私のポイントだと思う。潜在的にmyNonNullableIntはまだ設定されておらず、デフォルト値0の値を持ちます。これはnullよりもビジネスドメインで無効な値です。とにかくチェックしなければなりません。そして、私はmyNullableInt!= nullをmyNonNullableInt> 0よりも優先します。 –

+0

非ローカルスコープであっても、必要に応じてヌル型を使用するのが理にかなっています。そのタイプの取引は余分な小切手などを必要とします。 – LukeH

0

私は、彼らが理にかなってどこNull許容型を使用する傾向がある - それは問題だまで、私はパフォーマンスを気にしないだろうし、私はそれがあり、それを行うことがいくつかの領域を修正します。

しかし、私は一般に、私の価値の大部分は最終的にはnullにできないことに気づきます。実際には、nullを取得したときにnull型の問題を調べるために参照型で使用できるNotNullableが好きです。

2

私は言語設計者は、 'デフォルトでnullableになる参照型'は間違いであり、nullableでないことが唯一の賢明なデフォルトであると感じていると思うし、ヌルネスにする必要があります。 (これは多くの現代の関数型言語の中でのやり方です。) "null"は通常、問題の山です。

+0

あなたは、言語デザイナーがヌルネスから「離れる」ことを望んでいますが、実際にはヌルにすることはできませんでした。参照型はデフォルトではnullのままであり、オプトアウトする方法はありません。私はあなたの推論を理解していません。 – Lucas

+1

ここでは、いくつかの言語設計者の立場を特徴付ける良い方法があります。値型と参照型の2種類があります。 nullable型とnullable型の2種類があります。すべての参照型がnull型で、すべての型がnullableではない型システムから始めました。その後、null値型を追加しました。しかし、ヌル値を持たない参照型を追加することは非常に難しいです。 4つの可能性のすべてを考慮に入れてタイプシステムを設計する方が良いでしょう。 –

+0

はい、エリックが言ったことは素晴らしいです。いくつかの相互運用シナリオ(SQLデータベースなど)では、値型のNULL可能性が特定の勝利であると付け加えます。しかし、一般的なソフトウェアエンジニアリングの観点からは、ほとんどのタイプのほとんどのコードでは一般的な勝利です。 – Brian

3

あなたはなぜ、私が今までにC#で非NULL可能なデータ型を使用したいと思う

... 2つの異なる質問を持っているように見えますか?

シンプルなのは、使用している値タイプのデータが実際に値を持つことがコンパイラによって保証されているからです。

デフォルトではnullを許可する型を選択し、明示的に意味がある場合はnull以外の型しか使用しないのはなぜですか?

すでにJoelが言及しているように、型は参照型の場合のみnullになります。値の型はコンパイラによって値が保証されます。あなたのプログラムが値を持つ変数に依存している場合、これはnull可能な型を選択しないことで望む動作です。

もちろん、あなたのデータがあなたのプログラムではない場所から来ている場合、すべての賭けはオフになっています。最も良い例は、データベースからのものです。データベースフィールドはnullになる可能性がありますので、プログラム変数がこの値を模倣するようにしてください。nullを表す「マジック」値(つまり-1、0など)を作成するだけでなく、 null可能な型でこれを行います。 NULL値は、「-まだ初期化されていない」または「-指定されていない」として使用するための便利なことができますが

+0

他の答え/コメントで述べたように、null可能な型*は値型ですが、値を持つことは保証されません。 – LukeH

+0

これは大丈夫です、彼は "null値ではない値の型"を意味しています:) – Lucas

0

値は、彼らはあなたがnullの意味をオーバーロードだけでなく、している主な理由は、コードをより複雑にします変数(number-or-null対just-a-number)。

NULL値は、多くのデータベース設計者やSQLデータベースプログラマに好まれますが、null値で取り除くことができ、実際にはより簡単で信頼性の高いコードを持つことができます(たとえば、NullReferenceException) 。

実際には「T!」という大きな需要があります。どのような参照型もnullにできないようにします。 C#の発明者であるAnders Hejlsberg氏は、値の型をヌルにすることを可能にしました。

も参照してください質問、あなたは常にNULL可能なタイプを使用してはならない理由Why is “null” present in C# and java?

0

Nullableタイプを使用する必要がある唯一の時間は、データベースのテーブルの特定のフィールドで、ある時点でアプリケーションがnullを送受信することが絶対に必要な場合です。このような場合でも、Nullable型を使用する方法を常に見つけようとする必要があります。ブールはいつもあなたの親友ではありません。

関連する問題