C#nullable intをintに変換する方法


484

nullable intをに変換するにはどうすればよいintですか?以下のように2種類のintがあるとします。

int? v1;  
int v2; 

v1値を割り当てたいのですがv2v2 = v1;エラーが発生します。どのように変換v1v2ますか?


の場合の望ましい動作v1null何ですか?
ソロモンウッコ

回答:


637

これまでの他の答えはすべて正しいです。もう少しクリーンなものを追加したかっただけです。

v2 = v1 ?? default(int);

Any Nullable<T>は暗黙的にそのTに変換できます。ただし、評価される式全体でValueTypeにnullが割り当てられることはありません。したがって、null融合演算子??は、3項演算子の構文糖衣です。

v2 = v1 == null ? default(int) : v1;

...これは、if / elseの構文糖です。

if(v1==null)
   v2 = default(int);
else
   v2 = v1;

また、.NET 4.0以降、Nullable<T>「GetValueOrDefault()」メソッドがあります。これは、基本的に上記のnull結合を実行するnullセーフゲッターであるため、これも機能します。

v2 = v1.GetValueOrDefault();

4
されてdefault(int)本当に必要?シンプルの何が問題になってい0ますか?
Cole Johnson、

4
この例では機能しますが、一般的なケースでdefaultは適切な場所で使用することをお勧めします。ゼロは値として常に有効であるとは限らず、デフォルトよりはるかに低いためint、ジェネリックに置き換えると、T私のコードは機能しますが、ゼロは機能しません。一部の将来のフレームワークバージョンでdefaultは、オーバーロード可能になる可能性もあります。その場合、デフォルトを使用するコードは簡単に利用できますが、明示的なnullまたはゼロの割り当ては変更する必要があります。
KeithS 2015年

5
これはトップに上がるはずです:.NET 4.0、Nullable <T>には「GetValueOrDefault()」があります
RandomHandle

GetValueOrDefaultで編集して戻ってきてくれてありがとう!
CindyH

デフォルトを使用する場合は、DateTimeに注意する必要があります。これにより、空ではなくデフォルトの日付が挿入される場合があります。
牧場Camal


92

Valueプロパティを割り当てに使用できます。

v2 = v1.Value;

8
また、v1にnullが含まれているかどうか不明な場合は、null結合演算子を使用してフォールバック値を設定できます。例:v2 = v1 ?? 0;
Arjen

12
そして、v1.HasValue最初に確認してください。
Yuck

3
MSDNによれば、これは例外v1ですnull。私の意見では、これは正しい答えではありません。
Veniseis

6
@ventiseis私はそれを望ましい動作だと思います-他の多くの答えがnullを静かに0に変換することに問題がないので驚いています。null許容型をnull不可型に割り当てる場合は、値は実際にはnullではありません。OPは「v1をv2に、またはv1がnullの場合は0に割り当てたい」とは言いませんでしたが、それが誰もが想定しているようでした
Michael Mrozek


49

v1値があることがわかっている場合は、Valueプロパティを使用できます。

v2 = v1.Value;

このGetValueOrDefaultメソッドを使用すると、値がある場合は値が割り当てられ、それ以外の場合はタイプのデフォルト、または指定したデフォルト値が割り当てられます。

v2 = v1.GetValueOrDefault(); // assigns zero if v1 has no value

v2 = v1.GetValueOrDefault(-1); // assigns -1 if v1 has no value

HasValueプロパティを使用しv1て、値があるかどうかを確認できます。

if (v1.HasValue) {
  v2 = v1.Value;
}

GetValueOrDefault(T)メソッドの言語サポートもあります。

v2 = v1 ?? -1;

最初に値があるかどうかを確認する前に値を使用しないでください。使用 ??代わりに演算子。
ピーター


28

GetValueOrDefault()

オブジェクトの値を取得します。nullの場合は、intのデフォルト値である0を返します。

例:

v2= v1.GetValueOrDefault();


21

特定のタイプのデフォルト値が許容可能な結果である場合:

if (v1.HasValue)
    v2 = v1.GetValueOrDefault();

結果が未定義のときに別のデフォルト値が必要な場合:

v2 = v1.GetValueOrDefault(255);    // or any valid value for int in place of 255

値を返すだけの場合(メソッドが失敗したかどうかに関係なく):

v2 = v1.GetValueOrDefault();


.NET 4.7.2 .: GetValueOrDefault()チェックなしでフィールド値を返します。




10

それは可能です v2 = Convert.ToInt32(v1);


これは技術的には機能しますが、HasValue / ValueやGetValueOrDefaultなどの他の手法ははるかに効率的に実行されます。
Brandon Barkley


9

間の単純な変換v1v2するので不可能であるv1よりも値の大きい領域を有していますv2。それは、すべてv1null状態に加えて、保持できるものです。変換するにはintnull状態のマッピングに使用される値を明示的に指定する必要があります。これを行う最も簡単な方法は??演算子です

v2 = v1 ?? 0;  // maps null of v1 to 0

これは長い形式でも行うことができます

int v2;
if (v1.HasValue) {
  v2 = v1.Value;
} else {
  v2 = 0;
}

9

使用状況に応じて、C#7のパターンマッチング機能を使用できます。

int? v1 = 100;
if (v1 is int v2)
{
    Console.WriteLine($"I'm not nullable anymore: {v2}");
}

編集:

一部の人々は説明を残さずに反対票を投じているので、これを実行可能な解決策として含めるための根拠を説明するためにいくつかの詳細を追加したいと思います。

  • C#7のパターンマッチングにより、値のタイプをチェックして暗黙的にキャストできるようになりました。上記のスニペットでは、if-conditionは、に格納されている値v1がの型と互換性がある場合にのみ渡されます。v2この場合はintです。の値がときということにv1あるnullヌルを割り当てることができないので、もし条件が失敗しますint。より適切にnullは、ではありませんint

  • このソリューションが常に最適な選択であるとは限らない可能性があることを強調したいと思います。私が提案するように、これは開発者の正確な使用状況に依存すると信じています。すでにがあり、割り当てられた値がnullでない場合にのみint?その値を条件付きで操作したい場合(これは、情報を失うことなくnull可能intを通常のintに安全に変換できる唯一の場合です)、パターンマッチングは、おそらくこれを行う最も簡潔な方法の1つです。


新しい変数名を導入する必要性は残念ですが、誤ってHasValueチェックをリファクタリングするリスクがないため、デフォルト値がない場合はこれが最良の(最も安全な)ソリューションです。
minexew

チェックとしてのv1.HasValueよりもこのメソッドの利点は見当たらず、次に、基礎となる値にアクセスするためのv1.Valueはありません。反対票を投じることはしませんが、この問題はすでに解決されており、新しい手法で問題が明確になることはないと思います。また、8〜9%遅いとベンチマークしました。
Brandon Barkley

それをベンチマークしていただきありがとうございます。どちらにしても、違いはせいぜいわずかです(私が想定している、時間的に重要な領域でこれを行わない限り)。APIではなく言語に組み込まれている構文糖に依存しているため、これはより「簡潔」または「慣用的」であると考えています。それは少し主観的ですが、おそらく「より保守可能」です。他の多くの回答が示唆するように、本当に、私はデフォルト値に依存するよりもこのアプローチが好きです。
ニコラスミラー

3

nullでない場合はv1toの値を割り当てv2、それ以外の場合はデフォルト値をゼロとします。

v2=v1??0

またはそれを書く別の方法です。

v2 = v1.HasValue?v1:0


-1
 int v2= Int32.Parse(v1.ToString());

5
このコードは質問に答えることがありますが、このコードが質問に答える理由および/または方法に関する追加のコンテキストを提供すると、その長期的な価値が向上します。
xiawi

1
アンダーハンドトリックを使用するよりも、「ベストプラクティス」の方法を使用してオプションをアンラップする方が適切です。参照については、docs.microsoft.com / en
us / dotnet / csharp / language

15の既存の回答で8年前の質問に回答する場合、回答の対象となっている質問の新しい側面を説明し、時間の経過によって回答が変わったかどうかを確認することが重要です。コードのみの回答は、ほとんどの場合、説明を追加することで改善できます。
Jason Aller
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.