27

私はただ自分の足を撃ち、この状況を可能にする実際の理由があったかどうか知りたいです。
そしてとにかく、この質問は将来のフットシューターの便宜のためにとどまることができます。


vb.netにnull許容値があるとします。

Dim i as Integer?

条件に基づいて、三項演算子を使用して値を割り当てたいと思います。これは、非常に優れているためです。

i = If(condition(), Nothing, 42)

つまり、条件がtrueである場合はnull可能性を使用し、そうでない場合は値を使用します。
その時点で射撃が行われます。明らかな理由はありませんが、VBコンパイラはとの共通ベースタイプを決定します。Nothingその時点で、VBコンパイラはステートメントを次のようにサイレントに変換しますIntegerInteger

i = If(condition(), 0, 42)

さて、これをC#で行う場合:

i = (condition()) ? null : 42;

<null>とうまく混ざらないというコンパイラエラーがすぐに発生しintます。今回はC#の方法で行っていたら、足が健康だったので、これは素晴らしいことです。そして、これをコンパイルするには、明示的に次のように記述する必要があります。

i = (condition()) ? null : (int?)42;

これで、 VBでも同じことができ、期待する正しいヌルネスを取得できます。

i = If(condition(), Nothing, CType(42, Integer?))

しかし、そもそも足を撃たなければなりません。コンパイラエラーや警告はありません。それはExplicit OnStrict Onです。


だから私の質問は、なぜですか?
これをコンパイラのバグと見なす必要がありますか?
または、コンパイラがこのように動作する理由を誰かが説明できますか?

4

7 に答える 7

35

これは、VBNothingがC#と直接同等ではないためnullです。

たとえば、C#では、このコードはコンパイルされません。

int i = null;

しかし、このVB.Netコードは問題なく機能します。

Dim i As Integer = Nothing

VB.NetNothingは、実際にはC#のdefault(T)式によく似ています。

于 2010-11-10T17:40:27.803 に答える
12

三項演算子は1つのタイプのみを返すことができます。

C#では、とに基づいてタイプを選択しようとしnullます42。さて、null型がないので、三項演算子の戻り型は42;の型であると判断します。昔ながらのint。次に、nullをプレーンな古いものとして返すことができないため、文句を言いますint。42をを強制するint?と、三項演算子はを返すint?ので、はnull有効です。

さて、VBについてはわかりませんが、MSDNから引用すると、
Assigning Nothing to a variable sets it to the default value for its declared type.

これは、VBが三項演算子がint(C#が行ったのと同じプロセスを使用して)を返すと判断するため、Nothingです0。繰り返しになりますが、を強制する42と、デフォルト値のになります。これは、予想どおりです。int?Nothingint?null

于 2010-11-10T17:53:51.467 に答える
2

Nothingnull同じものではありません...MSDNから:

変数にNothingを割り当てると、宣言された型のデフォルト値に設定されます。

また

式で値型を指定すると、IsNothingは常にFalseを返します。

そのintを覚えていますか?null許容型ですが、それでも値型であり、参照型ではありません。

DbNull.Valueの代わりにに設定してみてくださいNothing...

于 2010-11-10T17:48:06.937 に答える
2

これは、NothingよりもIFと関係があると思います。このコードを考えてみましょう:

''#     This raises an exception
Dim x As Integer?
x = If(True, Nothing, Nothing)
MessageBox.Show(x.Value)

''#     As does 
Dim x As Integer?
x = Nothing
MessageBox.Show(x.Value)

''#     Changing one of the truthpart arguments of If is what seems to return the zero.
Dim x As Integer?
x = If(True, Nothing, 5)
MessageBox.Show(x.Value)

なぜそれがこれを行っているのか私はまだ知りません、おそらくVBチームへの質問です。NothingキーワードやNullableとは関係ないと思います。

于 2010-11-10T18:06:08.707 に答える
1

多くの場合Nothing、デフォルト値に変換されます。使用するNothingのと同じ方法で使用するnullには、正しいnull許容型にキャストする必要があります。

Dim str As String
Dim int As Nullable(Of Integer) ' or use As Integer?
Dim reader As SqlDataReader
Dim colA As Integer = reader.GetOrdinal("colA")
Dim colB As Integer = reader.GetOrdinal("colB")
str = If(reader.IsDBNull(colA), DirectCast(Nothing, String), reader.GetString(colA))
int = If(reader.IsDBNull(colB), DirectCast(Nothing, Nullable(Of Integer)), reader.GetInt32(colB))
于 2013-06-29T08:34:40.550 に答える
-1

これは、整数が参照型ではないために発生します。「Nothing」は、参照型に対してのみ機能することになっています。Nothingを割り当てる値タイプの場合、デフォルト値に自動的に変換されます。これは、整数0の場合です。

于 2010-11-10T17:49:11.707 に答える
-1

これは、VS2015で(少なくとも)New Integerを使用することで実際に可能になりましたか?

元。:

If(testInt> 0、testInt、New Integer?)、ここでtestIntは整数型ですか?

于 2017-12-06T21:51:47.980 に答える