C#の文法でコンパイルが通らない理由について

このQ&Aのポイント
  • C#の文法でコンパイルが通らない理由について説明します。
  • 2つのプログラムの違いとコンパイル結果について説明します。
  • プログラムのコンパイルにおける文法的な違いにより、コンパイルが通らない場合があります。
回答を見る
  • ベストアンサー

C# この文法でコンパイルが通らないのは何故?

下記のような2つのプログラムがあり、一方はコンパイルが通らず、もう一方はコンパイルが通ります。 文法上の違いはさほどないと思うのですが、何故このような結果になるのでしょうか? /////////////////////////コンパイルNG///////////////////////// using System; class Class1{ public static void Main(){ Class2 x; //違い! Class2 xをここで定義 try{x = new Class2(100);} catch{} Console.WriteLine(x.z); } } class Class2{ public int z; public Class2(int x){ z=x; } } /////////////////////////////////////////////////////////// /////////////////////////コンパイルOK///////////////////////// using System; class Class1{ static Class2 x; //違い! Class2 xをここで定義 public static void Main(){ try{x = new Class2(100);} catch{} Console.WriteLine(x.z); } } class Class2{ public int z; public Class2(int x){ z=x; } } ///////////////////////////////////////////////////////////

  • jyuzou
  • お礼率77% (238/307)

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

  • ベストアンサー
  • UKY
  • ベストアンサー率50% (604/1207)
回答No.1

NG の方ではメソッド内で変数 x が宣言してあります。 よって、変数は自動的には初期化されないので、参照する前に確実に代入する必要があります。 try{x = new Class2(100);}catch{} では確実に代入したことにはなりません。代入が行われる前に例外が発生すると、代入しないまま次の処理に進んでしまうからです。 その後の Console.WriteLine(x.z); では、確実な代入がされていない変数 x を参照しているので、ここでエラーが出てコンパイルできません。 try{x = new Class2(100);}catch{} を x = new Class2(100); に書き換えると、確実に代入したことになるのでコンパイルできます。 OK の方では、メソッド内のローカル変数ではなくフィールドとして x が宣言してあります。 よって、変数は最初に null で初期化されます。つまり、初めから確実に代入してあるということです。 したがって、(Main メソッド内では確実な代入をしていませんが) コンパイルできます。

jyuzou
質問者

お礼

フィールド部で宣言するとnullで初期化されるんですね。 初めて知りました(苦笑) 丁寧な回答どうもありがとうございました。

関連するQ&A

  • C#でコンパイルができない。

    C#のベータ版をセットアップして以下のサンプルプログラムを コンパイルしたところ、エラーがでました。何がいけないのでしょうか?OSはWin98です。 css001.cs(7,3): error CS0117: 'System.Console' does not contain a definition for 'Writeline' using System; プログラムリスト public class CSS001 { public static void Main(string[] args) { Console.Writeline("Hello World"); } }

  • C# マルチスレッドにおける例外処理

    下記のようなデリゲートを利用したマルチスレッドのプログラムを組みました。 しかし、マルチスレッド内で例外がおきても、正常にプログラムが終了してしまいます。 (try-catchでも例外を捕捉できません) マルチスレッドプログラムにおいて、例外を捕捉するにはどうすれば、いいのでしょうか? using System; using System.Threading; class Class1 { delegate void delg(); public static void Main() { delg d = new delg(multi); d.BeginInvoke(new AsyncCallback(call), null); //マルチスレッド開始 System.Threading.Thread.Sleep(500); //マルチスレッドで例外を強制的に投げているので、 //ここまでたどり着く前にアプリケーションが落ちるはず。 //しかし、実際には正常終了。 Console.WriteLine("メインメソッド 正常終了"); } public static void multi() { Console.WriteLine("マルチスレッドで実行中"); throw new Exception(); //例外を強制的に投げる。 } public static void call(IAsyncResult ar) { Console.WriteLine("コールバックメソッド実行"); } }

  • Visual Studio 2017C#

    下記のVisual Studio 2017 C# 19行目のXの定義がありません。 と出ました。 11行目で定義していると思うのですけど…。 どういうことなのか教えてください。 ご多忙のところ恐れ入りますが、ご回答のほどよろしくお願いします。 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace jump25 { class Test { public int x = 10; } class Program { public static void Main(string[] args) { Test obj = new Test(); int y = object.x; Console.WriteLine(y); } } }

  • 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が出力されません・・どうすれば 出力されますか?

  • VC++2005について

    以下のソースですがVC++2005でコンパイルするとエラーになります。 どこを直せばよいのでしょうか? C#のソースですが、VC++2005との違いや、VC++2005のメリットなども知りたいです。 using namespace System; namespace Strings1 { class Class1 { static void Main(){ String^ jstr1 = "こんにちは"; Console::WriteLine( "\nみなさん" ); } } };

  • コンパイルエラー

    以下のようなソースファイルをコンパイルしたらコンパイルに失敗してしまいました。エラーは『Cls1はabstractで宣言する必要があります。show(int)をCls1で定義しません』と出ます。これはどういうことでしょうか。 interface Int1 { int x=100; void Show(int y); } class Cls1 implements Int1 { public void show(int x) { System.out.println(x); } } class Test12 { public static void main(String args[]) { Cls1 c; c = new Cls1(); c.show(200); } }

    • ベストアンサー
    • Java
  • コンパイラが見つかりません。

    いつも教えて頂きありがとうございます。 C#の勉強を始めました。 コードは下記の通りです。 using System; class Data{ public static void main() { int a; int b; a=2; b=3; a=b; Console.WriteLine(a); } } このコードに間違いないのですが 検索してもどうやってコンパイル(実行) するのか分りません。 ご回答の程、宜しくお願い申し上げます。

  • C#についての質問です

    Microsoft Visual C# 2010 Express をつかって using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Console { class Program { static void Main(string[] args) { Console.WriteLine("皆様、はじめまして"); } } } と入力して.csで保存したのですが、コマンドプロンプトで 'csc' は、内部コマンドまたは外部コマンド、 操作可能なプログラムまたはバッチ ファイルとして認識されていません。 とでてコンパイルできません。対応を教えてください。

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

    何故、実行結果が下記になるのか教えてください using System class Compare{ static void Main(){ int a = 10, b = 20; Console.WriteLine(" a = " + a + " b = " + b) } } 実行結果 a = 10 b = 20 (" a = " + a + " b = " + b) この式の計算の仕方を教えてください。 ご多忙中恐れ入りますが、宜しくお願い申し上げます

  • 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("引き分けです"); } } }