C#のnull許容の警告について

このQ&Aのポイント
  • C#のnull許容に関する警告を回避する方法について解説します。
  • null条件演算子を使用する方法や初期化や代入を使った方法について説明します。
  • 警告を回避するための正しい書き方について説明します。
回答を見る
  • ベストアンサー

C#のnull許容の警告について

「Visual Studio」のNET6.0の環境でコードを書いています。 static string UserName; という変数の宣言に対して 「null非許容のフィールドUserNameには、コンストラクターの終了時にnull以外の値が入っていなければなりません。フィールドをNULL許容として宣言することをご検討ください。」 という警告を回避するために static string? UserName; というnull条件演算子で対応したのですが、上司に 「トリッキーな方法(?)ではなく、初期化や代入を使え」 と言われてしまい static string UserName = null ; という書き方を試したのですが 「nullリテラルをnull非許容参照型に変換できません」 という警告が出てしまい、警告を出さない書き方が分からず困っている状態です。 どなたか修正方法を教えて頂けないでしょうか? 【ソースコード】 static class Program { static string UserName; static void Name() { Console.WriteLine("ユーザ名を入力してください"); string? enterName = Console.ReadLine(); Console.WriteLine("ユーザ名を入力してください: {0}", enterName); UserName = enterName; } 以下省略

質問者が選んだベストアンサー

  • ベストアンサー
  • chie65535
  • ベストアンサー率43% (8516/19359)
回答No.1

static string UserName = ""; と、長さ0の文字列で初期化し「長さが0の場合はnullと同等の処理をする(つまり、何も代入されていないとして扱う)」ようにする。 また、値を代入する際は「必ず長さ1以上の文字列を代入する」ようにして、「何も代入されていない状態に戻す場合」は、長さ0の文字列を代入するようにする。 なので、 string? enterName = Console.ReadLine(); で「長さ0の文字列が入力された場合」には、何か入力するまで入力を繰り返すようにしなければならない。 何故なら「長さ0の文字列が入力された場合」に UserName = enterName; を行うと「何も代入されていない状態」になってしまうから。

asai555666
質問者

お礼

ありがとうございました。

関連するQ&A

  • C#の数値の出力について

    下記のコードで cntLose の変数の数値を、コンソールに出力したいのですが、やり方が分からず、どなたか教えて頂けないでしょうか? 【ソースコード】 static class Program { static string userName; static int cntWin = 0; //勝利回数 static int cntLose = 0; //敗北回数 static int cntDraw = 0; //引分回数 //ユーザー名の入力 static void Main(string[] args) { string enterName = Console.ReadLine(); Console.WriteLine("ユーザ名を入力してください: {0}", enterName); userName = enterName; Start(); Resurut(); } static void Janken(ref string myHand) { // Random クラスの新しいインスタンスを生成する Random ran = new System.Random(); //コンピュータの出す手を1以上3以下に設定する。 string[] com = new string[] { "1", "2", "3" }; string con = com[ran.Next(3)]; //コンピュータが勝利した場合 if (((myHand == "1") && (con == "3")) || ((myHand == "2") && (con == "1")) || ((myHand == "3") && (con == "2"))) { Console.WriteLine("LOSE"); cntLose++; //敗北回数に加算 Console.WriteLine("{0}:cntWin勝、CPU:cntLose勝", userName); }

  • C#のメンバ変数について

    下記のコードで enterName の変数を static void Resurut() のメソッドへの受け渡しが上手くいかず、どなたか修正点を教えて頂けないでしょうか? 【ソースコード】 static class Program { static string enterName; static int cntWin = 0; //勝利回数 static int cntLose = 0; //敗北回数 static int cntDraw = 0; //引分回数 //ユーザー名の入力 static void Main(string[] args) { string enterName = Console.ReadLine(); Console.WriteLine("ユーザ名を入力してください: {0}", enterName); Start(); Resurut(); } *一部省略 static void Resurut() { if (cntWin > cntLose) { Console.WriteLine("{0}さんの総合勝利です", enterName); } else if (cntLose > cntWin) { Console.WriteLine("CPUの総合勝利です"); } else if (cntWin == cntLose) { Console.WriteLine("引き分けです"); } } }

  • C#のループについて

    現在C#でジャンケンゲームの課題に取り組んでいるのですが、ループ処理や各メソッドに対しての変数にエラーがでてしまい、修正方法が分からず、どなたか教えて頂けないでしょうか? ・ユーザはグー、チョキ、パーをそれぞれ1、2、3の数字で入力する。 ・CPUは乱数を使って出す手を選ぶ。 ・5回勝負として、人間とコンピュータの勝った回数を数え、勝敗がつくたびに1回ずつ表示する。    あいこは決着がつくまで再勝負。途中でどちらかが3勝しても、5回最後まで勝負を続ける。   ・指定された範囲以外の値を入力したら負けにする 【実行例】  ユーザ名を入力してください:goto  手を入力してください(グー1、チョキ2、パー3): 1  CPU:チョキ  WIN  goto:1勝、CPU:0勝    手を入力してください(グー1、チョキ2、パー3): 3  CPU:パー  DRAW    手を入力してください(グー1、チョキ2、パー3): 3  CPU:チョキ  LOSE  goto:1勝、CPU:1勝    手を入力してください(グー1、チョキ2、パー3): 0  LOSE(反則負け)  goto:1勝、CPU:2勝    (中略)    goto:3勝、CPU:2勝  gotoさんの総合勝利です! using System; namespace Ensyuu007 { static class Program { static string? Myhand; static int CntWin = 0; //勝利回数 static int CntLose = 0; //敗北回数 static int CntDraw = 0; //引分回数 //ユーザー名の入力 static void Main(string[] args) { string EnterName = Console.ReadLine(); Console.WriteLine("ユーザ名を入力してください: {0}", EnterName); Console.ReadLine(); } //じゃんけんを5回行います。 for (int GameCnt = 0; GameCnt <= 5; GameCnt++) { //正しく入力されたかチェックを行うメソッド。 static string Check(ref string Myhand) { static = Console.ReadLine(); Console.WriteLine("手を入力してください(グー1、チョキ2、パー3):{0}", Myhand); //正しく入力されたかチェックします。 Check(ref Myhand); //0,1,2が入力された場合 if (Myhand.Equals("1") || Myhand.Equals("2") || Myhand.Equals("3")) { //入力した数字をそのまま返します。 return Myhand; } //1,2,3以外が入力された場合 else { Console.WriteLine("LOSE(反則負け)"); return Myhand; } } //じゃんけんを開始するメソッド。 static void Start() { //コンピューターとじゃんけんさせます。 Janken(ref Myhand); Console.ReadLine(); } //コンピュータと自分の入力した手を判別するメソッド static void Janken(ref string Myhand) { // Random クラスの新しいインスタンスを生成する Random ran = new System.Random(); //コンピュータの出す手を1以上3以下に設定する。 string[] com = new string[] { "1", "2", "3" }; string con = ran.Next(3).ToString(); //配列型、変数teに出す名前を設定 string[] te = { "グー", "チョキ", "パー" }; //コンピュータが勝利した場合 if (((Myhand == "1") && (con == "3")) || ((Myhand == "2") && (con == "1")) || ((Myhand == "3") && (con == "0"))) { Console.WriteLine("あなた:" + te.GetValue(int.Parse(Myhand))); Console.WriteLine("コンピュータ:" + te.GetValue(int.Parse(con))); Console.WriteLine("LOSE"); CntLose++; //敗北回数に加算 } //自分が勝利した場合 else if (((Myhand == "1") && (con == "2")) || ((Myhand == "2") && (con == "3")) || ((Myhand == "3") && (con == "1"))) { Console.WriteLine("あなた:" + te.GetValue(int.Parse(Myhand))); Console.WriteLine("コンピュータ:" + te.GetValue(int.Parse(con))); Console.WriteLine("WIN"); CntWin++; //勝利回数に加算 } //あいこだった場合 else { Console.WriteLine("あなた:" + te.GetValue(int.Parse(Myhand))); Console.WriteLine("コンピュータ:" + te.GetValue(int.Parse(con))); Console.WriteLine("DRAW"); CntDraw++; //引分回数に加算 } } } static void Resurut() { if (CntWin > CntLose) { Console.WriteLine("総合勝利です"); } else if (CntLose < CntWin) { Console.WriteLine("CPUの総合勝利です"); }

  • C#の変数の範囲

    C#の変数の範囲 質問させてください。 以下は、ネットに掲載されていたC#の問題です。 ~ここから~ 下記のC#のコードを実行した場合、"Hello World!"と二行表示されます。 using System; class Program { static void Main(string[] args) { string s = "Hello"; Action a = () => Console.WriteLine(s); s += " World!"; a(); Console.WriteLine(s); } これを一行目だけ"Hello"と表示される場合、 Action a = () => Console.WriteLine(s);をどう書き換えればよいでしょうか。 1. Action a = () => Console.WriteLine("Hello!"); 2. Action<string> a = (s) => Console.WriteLine(s); 3. Action a = () => Console.WriteLine(t - " World!"); 4. string t = s; Action a = () => Console.WriteLine(t); 5. Action a = () => { string t = s; Console.WriteLine(t); }; ~ここまで~ 正解は4だそうですが、「何故」そうなるかがわかりません。 汗 私としては、1.4.も題意を満たす気がするのですが・・・。 お知恵をお貸しください。 出展 http://www.atmarkit.co.jp/fdotnet/extremecs/extremecs_07/extremecs_07_10.html

  • C#で独自の型を定義したい

    C# 2010 version 4.0を使用しています。 次のようなint型とstring型を混合したMixedという型を定義したいのですが、 public class Mixed { private int _TheInt = 0; public int TheInt { get { return _TheInt; } set { _TheInt = value; } } private string _TheString = null; public string TheString { get { return _TheString; } set { _TheString = value; } } public static implicit operator int(Mixed m) { return m.TheInt; } public static implicit operator Mixed(int x) { Mixed m = new Mixed(); m.TheInt = x; return m; } public static implicit operator string(Mixed m) { return m.TheString; } public static implicit operator Mixed(string x) { Mixed m = new Mixed(); m.TheString = x; return m; } } //Mixed m = 1; //Console.WriteLine(m); //これだとコンパイルエラーになる //Console.WriteLine(m.TheInt.ToString()); //「1」と表示される int i = 1; Console.WriteLine(i); //「1」と表示される object o = 1; Console.WriteLine(o); //「1」と表示される Console.WriteLineなどで表示する場合に 例えばint型なら int i = 1; Console.WriteLine(i); //「1」と表示される という具合にそのまま「1」と表示されます。 でもこのMixedの場合、 Mixed m = 1; Console.WriteLine(m.TheInt.ToString()); //「1」と表示される これでは「1」と表示されるのですが、 Console.WriteLine(m); //これだとコンパイルエラーになる このやり方だとエラーになります。 なんとかしてint型やobject型のようにToString()を使わずに 表示させることはできないでしょうか?

  • C#を教えてください。

    下記のコードで33個のエラーが出てきました。 Visual Studio 2017 C#でです。 ボクは忠実にコードを写しました。 重大度レベル コード 説明 プロジェクト ファイル 行 抑制状態 エラー CS0103 名前 'answer' は、現在のコンテキストに存在しません。 jump14 C:\Users\kouzo\source\repos\jump14\jump14\Program.cs 20 アクティブ 重大度レベル コード 説明 プロジェクト ファイル 行 抑制状態 エラー CS1002 ; が必要です。 jump14 C:\Users\kouzo\source\repos\jump14\jump14\Program.cs 12 アクティブ など納得の行かないエラーメッセージばかりです。 何故でしょうか? ご回答のほど宜しくお願い申し上げます。 namespace jump14 { class Program { static void Main(string[] args) string right = "正解", wrong = "不正解"; bool value; value = true; string answer = value ? right : wrong; Console.WriteLine(answer); value = false; answer = value ? right : wrong; Console.WriteLine(answer); } }

  • C#での関数テーブルの作り方

    同じ質問で昔以下の回答がありましたが、今はライブラリが進歩しているようなので、より新しい構文を使った書き方がありましたら、是非ご教授いただければと思います。 delegate bool Execute( string oprand ); class Entry {  static bool aaa(string op)   { System.Console.WriteLine("aaa "+op); return true; }  static bool bbb(string op)   { System.Console.WriteLine("bbb "+op); return true; }  static bool ccc(string op)   { System.Console.WriteLine("ccc "+op); return true; }  static public void Main() {   System.Collections.Generic.Dictionary<string,Execute> map =    new System.Collections.Generic.Dictionary<string,Execute>();   map["AAA"] = aaa;   map["BBB"] = bbb;   map["CCC"] = ccc;   map["BBB"]("argument");  } } 宜しくお願い致します。

  • C#について

    using System; class AddressBook: PhoneBook { private string address; public AddressBook() : base() { address=""; } public void Input() { base.Input(); Console.Write("住所?"); string address=Console.ReadLine(); } public void Writes() { base.Write(); Console.WriteLine("住所:{0}",address); } } class kadai62 { public static void Main() { Console.Write("電話帳に入力する人数を入れてください:"); int n = int.Parse(Console.ReadLine()); AddressBook[] pb = new AddressBook[n]; int i; for (i = 0; i < pb.Length; i++) { pb[i] = new AddressBook(); Console.WriteLine("{0}番目を入力してください.", i+1); pb[i].Input(); } Console.WriteLine(); while(true) { Console.Write("どこから探しますか?[1:氏名,2:自宅電話,3:携帯電話,0:終了] "); int t = int.Parse(Console.ReadLine()); if (t == 0) break; Console.Write("探す文字列は?"); string s = Console.ReadLine(); for (i = 0; i < pb.Length; i++) { if (pb[i].Search(t, s)) pb[i].Writes(); } } } } このプログラムで public void Writes() { base.Write(); Console.WriteLine("住所:{0}",address); } のaddressが出力されません・・どうすれば 出力されますか?

  • C#のdelegateについて

    C#におけるdelegateという仕様って javascriptやPHPにおける無名関数と同じものとおもってさしつかえないのでしょうか? たとえば (1) var funcObj = function (){ alert("無名関数だよ"); }; funcObj(); ーーーーーーーーーーーーーーーーー (2) $func =function(){ print("無名関数"); }; $func(); といった類のもの? たとえば以下のようなC#のコードだと using System; class MainClass{ //delegateの宣言 public delegate void MyMethod(string message); public delegate void NoneMethod(string aaa); public static void Main (string [] args){ //delegateの中身を記述 MyMethod methodA = delegate(string messageA){ Console.WriteLine(messageA); }; //無名関数?として実行 methodA("無名関数?"); //delegateをnewして使用する。 NoneMethod obj =new NoneMethod(OriginalMethod); obj("newして利用する無名関数"); } //delegateの中身を記述 public static void OriginalMethod(string aaa){ Console.WriteLine(aaa); } } 二種類delegateとおもわれるコードを書いております。 この delegateというキーワードをつかってまさに、冒頭のjsやPHPのようなスクリプト言語の ような感じで定義するdelegateと 宣言したdelegateを newしてまるでクラスのように扱う方法 のdelegate この二つの違いはなんでしょうか? バージョンによる、あたらしいか古いかだけですか?

  • C#の例外処理について

    下記のコードに対して、メンターから ・try ~ catch を使用する ・例外 exceptionをハンドリングする との指示を受けたのですが、コードに上手くあてはめれず、どなたか書き方を教えて頂けないでしょうか? 【ソースコード】 static void Start() { int gameNum; Console.WriteLine("勝負回数を入力してください"); //入力された文字が数値に変換出来なかった場合、inputerrorを表示させループさせる while (true) { var enter = Console.ReadLine(); var success = int.TryParse(enter, out gameNum); if (success) { break; } Console.WriteLine("inputerror"); }

専門家に質問してみよう