LoginSignup
icoke
@icoke

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

CS8602

Q&AClosed

CS8602 null参照の可能性があるものの逆参照

visual stadio 2022C#コンソールアプリで、string str = Console.ReadLine();などを使うと、上記のような警告文が出るのですがどう対応したらよいのでしょうか?
書き方が悪いのかif ( str == null ) { }や、try { } catch { }を使っても回避できませんでした。

追記
すみません。正確には、string[] strs = Console.ReadLine().Split();です。

1

4Answer

すみません。正確には、string[] strs = Console.ReadLine.Split();です。

それも間違っていて、

string[] strs = Console.ReadLine().Split();

ですよね?

であれば、Console.ReadLine() が null になる可能性があると言ってます。

解決策の一例は:

string[]? strs = Console.ReadLine()?.Split();

意味は分かりますか?

1

Comments

  1. @icoke

    Questioner

    はい、それは分かるんですが、nullを逆参照した時のエラー処理をどうすればいいのか、自分はtry catchifを使っても警告を回避できなかったので、その警告を回避する方法が知りたいのです。

  2. @icoke

    Questioner

    string[] strs = Console.ReadLine().Split();
    ですよね?

    はいそうです。それはここQiitaに書き込むときに間違えただけで、実際にはちゃんとConsole.ReadLine()と書いています。

  3. @icoke

    Questioner

    .ReadLine()の方もnull許容型すればよかったんですね。string[]?にするだけだと警告が消えなかったので分かりませんでした。ありがとうございます。

  4. それはここQiitaに書き込むときに間違えただけで、実際にはちゃんとConsole.ReadLine()と書いています。

    コードを提示する場合はそういう間違いがないように Visual Studio のエディタからコピペしてください。コードが提示してある場合は、それが質問者さんのやってることを語っていると思われます。なのでそれが間違っていると話の前提からして質問が成り立ちません。

    .ReadLine()の方もnull許容型すればよかったんですね。string[]?にするだけだと警告が消えなかったので分かりませんでした。

    違いますね。.ReadLine()?. の ? は null 許容型の ? とは違います。「null 条件演算子」です。

    null 条件演算子 ?. および ?[]
    https://learn.microsoft.com/ja-jp/dotnet/csharp/language-reference/operators/member-access-operators#null-conditional-operators--and-

  5. @icoke

    Questioner

    null許容型とは違うんですね、調べてみます。ありがとうございます。

  6. それはここQiitaに書き込むときに間違えただけで

    間違えたこと反省してないよね。あなたが間違ったせいで私は無駄な時間と労力を費やしたのですよ。多分他の閲覧者も。反省してるんだったら質問欄を編集して訂正してください。

  7. @icoke

    Questioner

    お手を煩わせてしまって申し訳ありません

・null 免除演算子
・NotNullWhenAttribute
・NotNullIfNotNullAttribute
辺りを参考にしてはいかがでしょうか?

1
string[] strs = Console.ReadLine().Split();

これは

string? line = Console.ReadLine();
string[] strs = line.Split();

と書くことができ、エラーになってるのは .Split() の呼び出しです。
CS8602 は CS とつく様に コンパイラが出している警告なので、実際の値ではなく、型の問題を上げてる形となる為、それは try catch で解決できるものではありません。

コンパイラの前で null でないことを見せつけてやればいいので

  • ? で null の時は通らない様にする(この場合は null の場合は null が返るのでstring[]? となります。
string[]? strs = Console.ReadLine()?.Split();
  • ?? で null の場合の処理を書いて .Slipt() を呼び出す
string[] strs = (Console.ReadLine() ?? throw nw InvalidOperationException()).Split();
string[] strs = (Console.ReadLine() ?? string.Empty).Split();

あたりが思いつきますね。

勿論 泥臭く

string? line = Console.ReadLine();
if (string.IsNullOrEmpty(line))  throw nw InvalidOperationException();
string[] strs = line.Split();

としてもいいと思います。

1

Comments

  1. @icoke

    Questioner

    参考になります。ありがとうございます。

いろいろ試してみました。

・null 免除演算子

が一番よさそうです。.ReadLine()!とすると警告が消えました。
元々、null は入らない仕様のはずなので、これで行こうと思います。ありがとうございました。

0

Comments

  1. Ctrl+Z (※読み取り中断コマンド linux だと Ctrl+D) を押してから Enter すると null が返ってくるのは知りませんでした。(今確認した。

  2. null は入らない仕様

    それってオレオレ仕様になってませんか? ユーザーは想像を超えたことをするという前提に立って考えて、どうして null にならないことが保証できるのですか?

Your answer might help someone💌