Menu

C#のHello World:Main、Console.WriteLine、ReadLine

最初のC#のプログラムを1行ずつ解説します。Mainメソッド、Console.WriteLineとWrite、Console.ReadLineによる入力の読み取り、コメント、dotnet CLIによるプロジェクトの作成と実行、そしてトップレベルステートメントを扱います。

このページのコードはエディタで実行できます - 編集してすぐに結果を確認できます。

最初のプログラムの定番は、1行のテキストを表示するものです。C#では次のようになります。

出力:

Hello, World!

1行ずつ見る

  • using System; を書くと、完全な名前 System.Console の代わりに Console と書けます。Console は System 名前空間のクラスです(名前空間とusingを参照)。
  • class Program はクラスを宣言します。C#のすべてのコードは型の中にあります。Program という名前は慣例であって、必須ではありません。
  • static void Main() はエントリポイントです。プログラムが始まると、ランタイムは Main という名前の静的メソッドを探して呼び出します。static はクラス自体に属することを意味するので、先にオブジェクトを作る必要はありません。void は何も返さないことを意味します。
  • Console.WriteLine("Hello, World!"); は、文字列の引数を付けて WriteLine メソッドを呼び出します。すべての文はセミコロンで終わります。
  • 波かっこ { } は、クラスとメソッドの本体を表します。

C#は大文字と小文字を区別します。console.writeline と main は Console.WriteLine と Main とは別の名前で、どちらも存在しません。

Console.WriteLineとConsole.Write

WriteLine はテキストの後に改行を加えます。Write は加えないので、次の出力は同じ行に続きます。どちらも文字列だけでなく任意の型を受け付けます。数値、ブール値、オブジェクトは ToString() メソッドで変換されます。

出力:

Loading.. done
42
True

Item: coffee
coffee costs 3.20
coffee costs 3.20

true が True と表示されることに注目してください。これは bool.ToString() が返すものです。文字列補間と呼ばれる $"..." の形が、最もよく使うものになります。:F2 のような書式コードについては文字列補間を参照してください。

Console.ReadLineで入力を読む

Console.ReadLine() は、ユーザーが1行入力してEnterを押すのを待ち、その行を改行なしの string として返します。入力の終わり(たとえば、ファイルからリダイレクトされた入力が尽きたとき)には null を返します。

出力:

What is your name? How old are you? 
Hi Maya, next year you will be 28.

これをターミナルで実行すると、入力したテキストが各プロンプトの後に表示されます。上の出力に入力したテキストがないのは、入力を打ち込んだのではなくリダイレクト(パイプ)したので、プログラム自身が書き出したものだけが表示されているからです。

ReadLine は常にテキストを返します。値を数値として使うには変換が必要です。int.Parse(text) はテキストが数値でないと FormatException を投げます。int.TryParse は代わりに false を返すので、ユーザーの入力にはこちらが適しています。詳しくは型変換で扱います。

関連するメソッドが2つあります。Console.Read() は次の文字を int のコードとして返し、Console.ReadKey() はEnterを待たずに1回のキー入力を読みます(対話的なターミナルでしか動きません)。

Mainメソッドの他の形

Main はコマンドライン引数を受け取ることができ、終了コードを返すこともできます。次のどれも有効なエントリポイントです。

static void Main()
static void Main(string[] args)
static int Main()
static int Main(string[] args)
static async Task Main()             // C# 7.1 and later
static async Task<int> Main(string[] args)  // C# 7.1 and later

返された int はプロセスの終了コードになり、スクリプトやCIシステムはそれを読んでプログラムが成功したかどうかを判断します(慣例で0が成功です)。

出力:

Got 0 argument(s)

dotnet run -- apples pears で実行すると、args には "apples" と "pears" が入ります。-- は、プログラムへの引数と dotnet ツールへの引数を区切ります。

コメント

C#には3種類のコメントがあります。コンパイラはそのすべてを無視します。

// A single-line comment runs to the end of the line.

/* A block comment
   can span several lines. */

/// <summary>
/// An XML documentation comment. Editors show it as the tooltip for the method.
/// </summary>
static decimal ApplyDiscount(decimal price) => price * 0.9m;

コードの中のメモには // を使います。/// のコメントは型や公開メンバーに付けます。IDEは呼び出しにカーソルを合わせたときにそれを表示し、コンパイラはドキュメントツールのためにXMLファイルへ書き出すこともできます。

dotnetでプロジェクトを作成して実行する

自分のマシンでは、dotnet.microsoft.comから.NET SDKをインストールしてから、次のようにします。

dotnet new console -o HelloApp
cd HelloApp
dotnet run
Hello, World!

dotnet new console は2つのファイルを作ります。HelloApp.csproj(プロジェクトファイル:ターゲットフレームワーク、設定、パッケージ参照)と Program.cs です。dotnet run はプロジェクトをコンパイルして実行します。dotnet build は実行せずにコンパイルし、出力を bin/Debug/net8.0/ に書き込みます(フォルダー名はターゲットフレームワークに従います)。

トップレベルステートメント(C# 9以降)

生成された Program.cs を開くと、これだけが書かれています。

// See https://aka.ms/new-console-template for more information
Console.WriteLine("Hello, World!");

これはC# 9の機能であるトップレベルステートメントのプログラムです。コンパイラが、文の周りに Program クラスと Main メソッドを生成します。using System; もありませんが、これは.NET 6以降のプロジェクトで暗黙的なusingが有効になっているからです。System、System.IO、System.Linq、System.Collections.Generic などのよく使う名前空間が、プロジェクト全体にインポートされています。

トップレベルのプログラムでも、args を読み、await を使い、終了コードを return できます。

// C# 9 and later: the whole Program.cs
Console.Write("Name: ");
string? name = Console.ReadLine();
Console.WriteLine($"Hello, {name}! You passed {args.Length} arguments.");
return 0;

トップレベルステートメントを書けるのはプロジェクトごとに1つのファイルだけで、型(クラス、レコード)はそれらの後に置かなければなりません。string? の注釈はnull許容参照型(C# 8)で、ReadLine が null を返しうるので付いています。このページの例で使っている明示的な class Program の形は同等で、古いコードやほとんどのUnityのスクリプトで目にするものなので、両方を読めるようにしておく価値があります。新しいプロジェクトで明示的な形を使いたいなら、dotnet new console に --use-program-main を渡します。

最初に目にするエラー

  • CS1002: ; expected。 文のセミコロンが抜けています。エラーは、セミコロンが抜けている行の末尾で報告されます。
  • CS0103: The name 'console' does not exist in the current context。 大文字と小文字の間違いか、暗黙的なusingのないプロジェクトで using System; が抜けています。
  • CS5001: Program does not contain a static 'Main' method suitable for an entry point。 Main の綴りが間違っているか、static でないか、サポートされていないシグネチャです。
  • CS0017: Program has more than one entry point defined。 2つのクラスがそれぞれ Main を持っています。1つだけ残すか、.csproj の StartupObject の設定で1つを選びます。
  • ウィンドウがすぐに閉じる。 コンソールアプリをダブルクリックで起動すると、Main が戻った時点でウィンドウが閉じます。ターミナルから実行するか、テスト中は最後に Console.ReadKey(); を追加します。

よくある質問

C#でHello Worldはどう書きますか?

ファイルの先頭に using System; を書き、クラスの static void Main() メソッドの中に Console.WriteLine("Hello, World!"); を置きます。.NET 6以降で dotnet new console によって作ったプロジェクトなら、トップレベルステートメントがクラスと Main を生成してくれるので、ファイル全体がその1行だけで済みます。

C#のMainメソッドとは何ですか?

Main はエントリポイント、つまりプログラムの開始時にランタイムが呼び出すメソッドです。static でなければならず、void か int(終了コード)を返せ、コマンドライン引数を受け取る string[] args 引数を持てます。プログラムにはちょうど1つ必要です。

Console.WriteとConsole.WriteLineの違いは何ですか?

Console.WriteLine はテキストの後に改行を書くので、次の出力は新しい行から始まります。Console.Write はテキストだけを書くので、次の出力は同じ行に続きます。引数なしの Console.WriteLine() は空の行を出力します。

C#でユーザーの入力を読むには?

Console.ReadLine() はテキストを1行読み、それを(改行なしの)string として返し、入力がもうなければ null を返します。数値を得るには文字列を変換します。int.TryParse(Console.ReadLine(), out int n) は、テキストが数値でないときにクラッシュせず false を返します。

コマンドラインからC#のプログラムを実行するには?

.NET SDKをインストールし、dotnet new console -o HelloApp でプロジェクトを作り、cd HelloApp として、dotnet run でビルドして実行します。dotnet build はコンパイルだけを行い、出力を bin/Debug/net8.0/(またはターゲットのバージョンのフォルダー)に置きます。

Coddy programming languages illustration

Coddyでコードを学ぼう

始める