C#(csharp)文法入門|初心者が最初に覚える基本構文をわかりやすく解説

1. C#(csharp)文法とは?初心者が最初に理解すべき基本

C#文法とは、C#でプログラムを書くためのルールです。日本語に文法があるように、プログラミング言語にも、正しい記述方法や命令の組み立て方があります。

C#では、多くの命令の末尾にセミコロンを付けたり、複数の処理を波括弧で囲んだりします。まずは細かな機能を暗記するのではなく、「どの構文が何のためにあるのか」を理解することが大切です。

1-1. C#とはどんなプログラミング言語か

C#は、Microsoftによって開発されたオブジェクト指向プログラミング言語です。「シーシャープ」と読みます。

C#のコードは、主に.NETという実行環境上で動作します。文法は比較的読みやすく、型チェックなどの仕組みも充実しているため、初心者から実務の開発者まで幅広く利用されています。

C#には、次のような特徴があります。

  • 変数の型を明確に扱える

  • オブジェクト指向に対応している

  • 豊富な標準ライブラリを利用できる

  • Windows以外の環境でも動作させられる

  • 小規模なツールから大規模なシステムまで開発できる

C#はJavaやC++と似た記述も多いため、C#を学ぶことで、ほかのプログラミング言語を理解しやすくなる場合もあります。

1-2. C#でできること

C#では、さまざまな種類のアプリケーションを開発できます。

代表的な用途には、次のようなものがあります。

  • ASP.NET Coreを使ったWebアプリやWeb API

  • Windows向けデスクトップアプリ

  • Unityを使ったゲーム開発

  • スマートフォン向けアプリ

  • クラウド上で動くサービス

  • 社内向けの業務システム

  • データ処理や自動化ツール

  • IoT機器と連携するプログラム

学習を始める段階では、コンソールに文字や計算結果を表示する小さなプログラムから取り組むとよいでしょう。基本文法を覚えれば、その知識をWeb開発やゲーム開発にも応用できます。

1-3. C#とcsharp表記の違い

「C#」と「csharp」は、基本的に同じプログラミング言語を指します。

正式な表記はC#ですが、シャープ記号を入力しにくい環境や、URL、ファイル名、検索キーワードなどでは「csharp」と表記されることがあります。

たとえば、次の検索キーワードは、ほぼ同じ意味で使われます。

  • C# 文法

  • csharp 文法

  • C# 基本構文

  • csharp 入門

また、C#のソースコードを保存するファイルには、通常.csという拡張子が使われます。

Program.cs

「C#」と「csharp」は別の言語ではないため、どちらの表記で解説されていても、基本的には同じ内容だと考えて問題ありません。

1-4. C#文法を学ぶ前に知っておきたい前提知識

C#の学習を始める前に、次の用語を簡単に理解しておきましょう。

ソースコードは、人がプログラミング言語を使って記述した命令です。

コンパイルは、ソースコードをコンピューターが実行できる形式へ変換する処理です。

ビルドは、コンパイルを含め、プログラムを実行可能な状態にする一連の処理を指します。

実行は、作成したプログラムを実際に動かすことです。

C#を学習するには、Visual Studio、Visual Studio Code、JetBrains Riderなどの開発環境を利用できます。最初は、プロジェクトの作成や実行を簡単に行える環境を選ぶと学習しやすくなります。

2. C#の基本構造とプログラムの書き方

C#プログラムは、クラスやメソッドなどを組み合わせて作成します。最初に、文字を表示する簡単なプログラムを確認しましょう。

using System;

namespace SampleApp{class Program{static void Main(string[] args){Console.WriteLine("Hello, C#!");}}}

このコードを実行すると、コンソールに次の文字が表示されます。

Hello, C#!

2-1. C#プログラムの基本構成

従来のC#プログラムは、主に次の要素で構成されます。

using System;

namespace SampleApp{class Program{static void Main(string[] args){Console.WriteLine("プログラムを実行しました");}}}

それぞれの役割は次のとおりです。

  • using:利用する名前空間を指定する

  • namespace:クラスなどを分類する

  • class:データや処理をまとめる

  • Main:プログラムの開始地点になる

  • Console.WriteLine:コンソールに文字を表示する

波括弧の中には、その要素に属するコードを書きます。波括弧の対応関係がわかりにくいときは、インデントをそろえると構造を把握しやすくなります。

なお、新しい形式のC#プロジェクトでは、次のように短く書ける場合もあります。

Console.WriteLine("Hello, C#!");

これはトップレベルステートメントと呼ばれる書き方です。ただし、クラスやMainメソッドの仕組みは今後の学習でも必要になるため、従来の基本構造も理解しておきましょう。

2-2. Mainメソッドとは

Mainメソッドは、C#プログラムの実行開始地点です。

static void Main(string[] args){Console.WriteLine("開始");}

プログラムを実行すると、基本的にはMainメソッド内の命令が上から順番に処理されます。

static void Main(string[] args){Console.WriteLine("1番目");Console.WriteLine("2番目");Console.WriteLine("3番目");}

実行結果は次のようになります。

1番目2番目3番目

string[] argsには、プログラムの起動時に渡された文字列を受け取れます。初心者の段階では、「Mainがプログラムの入口になる」と理解しておけば十分です。

2-3. namespace・class・methodの役割

namespaceは、関連するクラスを分類するための仕組みです。同じ名前のクラスが複数存在するときに、名前の衝突を防ぐ役割もあります。

namespace MyApplication{class User{}}

classは、データと処理をひとまとめにする設計図です。

class User{public string Name { get; set; } = "";

public void Introduce(){Console.WriteLine($"私は{Name}です");}

}

methodは、複数の処理をまとめて名前を付けたものです。

static void SayHello(){Console.WriteLine("こんにちは");}

名前空間の中にクラスがあり、クラスの中にメソッドやプロパティがある、と考えると構造を理解しやすくなります。

2-4. コメントの書き方

コメントは、コードに説明を残すための記述です。コメントとして書いた内容は、プログラムの処理には影響しません。

1行だけコメントを書く場合は、//を使います。

// 名前を表示するConsole.WriteLine("佐藤");

複数行をコメントにする場合は、//で囲みます。

/*ここは複数行のコメントです。プログラムには実行されません。*/Console.WriteLine("C#を学習中です");

XMLドキュメントコメントでは、クラスやメソッドの説明を記述できます。

/// <summary>/// 2つの整数を足し算します。/// </summary>static int Add(int a, int b){return a + b;}

コメントを書きすぎるとコードが読みにくくなるため、処理の目的や、コードだけでは判断しにくい理由を説明するときに利用しましょう。

2-5. Console.WriteLineで文字を出力する方法

コンソールに文字を表示するには、Console.WriteLineを使います。

Console.WriteLine("C#の基本文法");

数値も出力できます。

Console.WriteLine(100);

変数の内容を表示することも可能です。

string name = "田中";Console.WriteLine(name);

文字列の中に変数を埋め込む場合は、文字列補間が便利です。文字列の先頭に$を付け、変数を波括弧で囲みます。

string name = "田中";int age = 25;

Console.WriteLine($"名前は{name}、年齢は{age}歳です");

改行せずに出力したい場合は、Console.Writeを使います。

Console.Write("こんにちは");Console.Write("C#");

実行結果は次のようになります。

こんにちはC#

3. C#の変数とデータ型

変数は、数値や文字列などのデータを一時的に保存するための箱です。C#では、変数を宣言するときに、基本的には保存するデータの型を指定します。

3-1. 変数の宣言と代入

変数を作成することを「宣言」といいます。

int age;

変数に値を入れることを「代入」といいます。

age = 20;

宣言と代入は、同時に記述できます。

int age = 20;

変数の値は、あとから変更できます。

int score = 80;score = 95;

Console.WriteLine(score);

実行結果は95です。

変数名には、そのデータの意味が伝わる名前を付けましょう。

int userAge = 20;string userName = "山田";

次のような名前では、用途がわかりにくくなります。

int a = 20;string x = "山田";

短い計算処理などでは短い名前が使われることもありますが、基本的には意味のある変数名を選びましょう。

3-2. int・double・string・boolの使い方

C#でよく使う基本的なデータ型には、intdoublestringboolがあります。

intは、整数を扱う型です。

int age = 30;int price = 1500;

doubleは、小数を扱う型です。

double height = 172.5;double taxRate = 0.1;

stringは、文字列を扱う型です。文字列はダブルクォーテーションで囲みます。

string name = "鈴木";string message = "C#を勉強しています";

boolは、真偽値を扱う型です。値にはtrueまたはfalseを使用します。

bool isActive = true;bool isCompleted = false;

それぞれの型をまとめて使うと、次のように書けます。

string productName = "ノート";int price = 300;double taxRate = 0.1;bool isAvailable = true;

Console.WriteLine($"商品名:{productName}");Console.WriteLine($"価格:{price}円");Console.WriteLine($"税率:{taxRate}");Console.WriteLine($"販売中:{isAvailable}");

3-3. varによる型推論

varを使うと、代入した値から変数の型を自動的に判断させられます。

var age = 20;var name = "佐藤";var rate = 1.5;var isEnabled = true;

このコードでは、各変数の型は次のように推論されます。

  • ageint

  • namestring

  • ratedouble

  • isEnabledbool

varは、どのような型でも自由に入れられる変数ではありません。一度型が決まると、異なる型の値は代入できません。

var age = 20;// age = "二十";  // コンパイルエラー

また、varを使う場合は、宣言と同時に初期値を代入する必要があります。

// var value;  // 型を判断できないためエラー

型が明らかな場合はvarを使うとコードを短くできます。ただし、型がわかりにくくなる場合は、intstringなどを明示したほうが読みやすくなります。

3-4. 定数constの使い方

あとから変更しない値には、constを使って定数を宣言できます。

const double TaxRate = 0.1;const int MaxScore = 100;

定数には、あとから別の値を代入できません。

const int MaxCount = 10;// MaxCount = 20;  // エラー

定数は、税率、上限値、固定メッセージなど、プログラム内で変化しない値に利用します。

const int AdultAge = 18;

int age = 20;bool isAdult = age >= AdultAge;

Console.WriteLine(isAdult);

C#では、定数名をパスカルケースで書くことが一般的です。

const int MaximumUserCount = 100;

3-5. 型変換とキャストの基本

異なるデータ型へ値を変換する処理を、型変換といいます。

intからdoubleへの変換は、データが失われにくいため自動的に行われます。

int number = 10;double result = number;

Console.WriteLine(result);

doubleからintへ変換する場合は、小数部分が失われる可能性があるため、キャストを明示します。

double price = 120.8;int result = (int)price;

Console.WriteLine(result);

実行結果は120です。四捨五入ではなく、小数部分が切り捨てられる点に注意しましょう。

文字列を数値へ変換するには、int.Parseを利用できます。

string text = "123";int number = int.Parse(text);

Console.WriteLine(number + 10);

ただし、数値に変換できない文字列をint.Parseに渡すと例外が発生します。安全に変換したい場合は、int.TryParseを使います。

string text = "123";

if (int.TryParse(text, out int number)){Console.WriteLine($"変換結果:{number}");}else{Console.WriteLine("数値に変換できません");}

数値を文字列へ変換する場合は、ToStringを使えます。

int number = 100;string text = number.ToString();

4. C#の演算子の基本

演算子は、計算、比較、代入などを行うための記号です。C#文法を学ぶうえで、演算子の使い方は欠かせません。

4-1. 算術演算子

算術演算子は、数値の計算に使用します。

int a = 10;int b = 3;

Console.WriteLine(a + b); // 加算:13Console.WriteLine(a - b); // 減算:7Console.WriteLine(a * b); // 乗算:30Console.WriteLine(a / b); // 除算:3Console.WriteLine(a % b); // 余り:1

主な算術演算子は次のとおりです。

  • +:足し算

  • -:引き算

  • *:掛け算

  • /:割り算

  • %:余り

整数同士の割り算では、小数部分が切り捨てられます。

int result = 10 / 3;Console.WriteLine(result);

実行結果は3です。小数まで求める場合は、少なくとも片方をdoubleにします。

double result = 10.0 / 3;Console.WriteLine(result);

4-2. 比較演算子

比較演算子は、2つの値を比較し、結果をtrueまたはfalseで返します。

int age = 20;

Console.WriteLine(age == 20); // trueConsole.WriteLine(age != 20); // falseConsole.WriteLine(age > 18); // trueConsole.WriteLine(age < 18); // falseConsole.WriteLine(age >= 20); // trueConsole.WriteLine(age <= 20); // true

主な比較演算子は次のとおりです。

  • ==:等しい

  • !=:等しくない

  • >:左側が大きい

  • <:左側が小さい

  • >=:左側が右側以上

  • <=:左側が右側以下

代入に使う=と、等しいか比較する==を混同しないように注意しましょう。

4-3. 論理演算子

論理演算子は、複数の条件を組み合わせるときに使います。

&&は、すべての条件が成立するときにtrueになります。

int age = 25;bool hasTicket = true;

if (age >= 18 && hasTicket){Console.WriteLine("入場できます");}

||は、いずれかの条件が成立するときにtrueになります。

bool isAdmin = false;bool isManager = true;

if (isAdmin || isManager){Console.WriteLine("管理画面を表示します");}

!は、真偽値を反転します。

bool isCompleted = false;

if (!isCompleted){Console.WriteLine("処理は完了していません");}

複雑な条件では、丸括弧を使って優先順位を明確にすると読みやすくなります。

if ((age >= 18 && hasTicket) || isAdmin){Console.WriteLine("入場できます");}

4-4. 代入演算子

代入演算子は、変数に値を代入するときに使います。

int score = 80;

現在の値を使って計算し、同じ変数へ代入する場合は、複合代入演算子を利用できます。

int number = 10;

number += 5; // number = number + 5number -= 2; // number = number - 2number *= 3; // number = number * 3number /= 2; // number = number / 2number %= 4; // number = number % 4

複合代入演算子を使うと、コードを短く書けます。

int totalPrice = 1000;totalPrice += 500;

Console.WriteLine(totalPrice);

実行結果は1500です。

4-5. インクリメント・デクリメント

変数の値を1増やす処理をインクリメント、1減らす処理をデクリメントといいます。

int count = 0;

count++;Console.WriteLine(count);

実行結果は1です。

count--;Console.WriteLine(count);

実行結果は0です。

++--には、変数の前に付ける書き方と、後ろに付ける書き方があります。

int a = 5;int b = a++;

Console.WriteLine(a); // 6Console.WriteLine(b); // 5

後置のa++では、代入に現在の値を使ったあと、aが1増えます。

int a = 5;int b = ++a;

Console.WriteLine(a); // 6Console.WriteLine(b); // 6

前置の++aでは、先に値を1増やしてから代入します。初心者のうちは、単独の行で使用すると混乱を避けやすくなります。

5. C#の条件分岐

条件分岐は、条件によって実行する処理を切り替える構文です。C#では、主にif文やswitch文を使います。

5-1. if文の基本構文

if文は、指定した条件がtrueのときだけ処理を実行します。

int age = 20;

if (age >= 18){Console.WriteLine("成人です");}

条件式は丸括弧の中に記述し、実行する処理は波括弧の中に書きます。

if (条件式){条件がtrueのときの処理}

bool型の変数を、そのまま条件にすることもできます。

bool isLoggedIn = true;

if (isLoggedIn){Console.WriteLine("ログイン済みです");}

処理が1行だけの場合は波括弧を省略できますが、処理の追加時にミスが起きやすくなるため、初心者は波括弧を書く習慣を付けるとよいでしょう。

5-2. else・else ifの使い方

条件が成立しなかった場合の処理は、elseで記述します。

int age = 16;

if (age >= 18){Console.WriteLine("成人です");}else{Console.WriteLine("未成年です");}

複数の条件を順番に確認する場合は、else ifを使います。

int score = 75;

if (score >= 90){Console.WriteLine("評価:A");}else if (score >= 70){Console.WriteLine("評価:B");}else if (score >= 50){Console.WriteLine("評価:C");}else{Console.WriteLine("不合格");}

条件は上から順番に判定されます。最初に成立した処理だけが実行され、それ以降の条件は確認されません。

そのため、点数のような範囲判定では、大きな値の条件から書くと意図した結果になりやすくなります。

5-3. switch文の基本

switch文は、1つの値に対して複数の分岐を作るときに便利です。

int menuNumber = 2;

switch (menuNumber){case 1:Console.WriteLine("新規登録");break;

case 2:Console.WriteLine("データ検索");break;case 3:Console.WriteLine("終了");break;default:Console.WriteLine("無効な番号です");break;

}

caseには比較する値を指定します。どの値にも一致しなかった場合は、defaultの処理が実行されます。

文字列による分岐も可能です。

string command = "start";

switch (command){case "start":Console.WriteLine("開始します");break;

case "stop":Console.WriteLine("停止します");break;default:Console.WriteLine("不明なコマンドです");break;

}

値ごとに処理を分けたい場合はswitch、範囲や複雑な条件を扱う場合はifが適しています。

5-4. 三項演算子の使い方

三項演算子を使うと、簡単な条件分岐を1行で記述できます。

条件式 ? trueの場合の値 : falseの場合の値

たとえば、年齢に応じて文字列を切り替える場合は、次のように書けます。

int age = 20;string result = age >= 18 ? "成人" : "未成年";

Console.WriteLine(result);

次のif文と同じ意味です。

string result;

if (age >= 18){result = "成人";}else{result = "未成年";}

三項演算子は短い条件分岐には便利ですが、複雑な処理を詰め込むと読みにくくなります。条件が複数ある場合や、実行する処理が長い場合はif文を使いましょう。

5-5. 条件分岐で初心者が間違えやすいポイント

条件分岐では、代入演算子と比較演算子の違いに注意が必要です。

int number = 10;

if (number == 10){Console.WriteLine("10です");}

比較には==を使います。

また、複数の条件を組み合わせるときは、&&||の違いを確認しましょう。

int age = 20;bool hasPermission = false;

if (age >= 18 && hasPermission){Console.WriteLine("利用できます");}

この場合、両方の条件が成立しなければ処理されません。

条件の順番も重要です。

int score = 95;

if (score >= 50){Console.WriteLine("合格");}else if (score >= 90){Console.WriteLine("優秀");}

このコードでは、95点でも最初の条件に一致するため、「合格」と表示されます。「優秀」を表示したい場合は、より限定的な条件を先に書きます。

if (score >= 90){Console.WriteLine("優秀");}else if (score >= 50){Console.WriteLine("合格");}

6. C#の繰り返し処理

繰り返し処理は、同じ処理を複数回実行するための構文です。C#では、forwhiledo whileforeachなどを使います。

6-1. for文の基本構文

for文は、繰り返す回数が決まっている場合に適しています。

for (int i = 0; i < 5; i++){Console.WriteLine(i);}

実行結果は次のとおりです。

01234

for文の丸括弧内は、次の3つに分かれています。

for (初期化; 継続条件; 更新処理){繰り返す処理}

iを1から5まで表示する場合は、次のように書きます。

for (int i = 1; i <= 5; i++){Console.WriteLine(i);}

カウントダウンも可能です。

for (int i = 5; i >= 1; i--){Console.WriteLine(i);}

6-2. while文の基本構文

while文は、条件が成立している間、処理を繰り返します。

int count = 0;

while (count < 3){Console.WriteLine(count);count++;}

実行結果は次のとおりです。

012

while文では、繰り返しの中で条件に使う値を変更する必要があります。

int count = 0;

while (count < 3){Console.WriteLine(count);}

このコードではcountが変化しないため、条件が常に成立し、無限ループになります。

意図的に無限ループを作る場合は、次のように書くこともあります。

while (true){Console.WriteLine("処理中");

break;

}

6-3. do while文の使い方

do while文は、最初に処理を実行し、そのあとで条件を判定します。そのため、条件が最初からfalseでも最低1回は処理されます。

int count = 0;

do{Console.WriteLine(count);count++;}while (count < 3);

while文との違いを確認してみましょう。

int number = 10;

while (number < 5){Console.WriteLine("while");}

この処理は一度も実行されません。

int number = 10;

do{Console.WriteLine("do while");}while (number < 5);

こちらは条件が成立していなくても、一度だけ実行されます。

do while文の末尾にはセミコロンが必要です。

while (条件);

6-4. foreach文の使い方

foreach文は、配列やリストなどの要素を順番に取り出す構文です。

string[] names = { "佐藤", "鈴木", "高橋" };

foreach (string name in names){Console.WriteLine(name);}

実行結果は次のとおりです。

佐藤鈴木高橋

基本構文は次のようになります。

foreach (要素の型 変数名 in コレクション){処理}

型が明らかな場合は、varも使えます。

foreach (var name in names){Console.WriteLine(name);}

要素を先頭から順番に処理したいだけであれば、インデックス管理が不要なforeach文が便利です。

6-5. break・continueの使い方

breakは、繰り返し処理を途中で終了します。

for (int i = 1; i <= 10; i++){if (i == 5){break;}

Console.WriteLine(i);

}

実行結果は、1から4までです。

continueは、現在の繰り返しだけを中断し、次の繰り返しへ進みます。

for (int i = 1; i <= 5; i++){if (i == 3){continue;}

Console.WriteLine(i);

}

実行結果は次のとおりです。

1245

breakはループそのものを終了し、continueは現在の1回分だけを飛ばす、と覚えましょう。

7. C#の配列・リスト・コレクション

複数のデータをまとめて扱うには、配列やListなどのコレクションを利用します。

7-1. 配列の宣言と使い方

配列は、同じ型のデータを複数保存するための仕組みです。

int[] scores = { 80, 90, 70 };

配列の要素には、インデックスを指定してアクセスします。インデックスは0から始まります。

Console.WriteLine(scores[0]); // 80Console.WriteLine(scores[1]); // 90Console.WriteLine(scores[2]); // 70

要素の値を変更することもできます。

scores[0] = 100;

要素数を指定して配列を作成する方法もあります。

string[] names = new string[3];

names[0] = "佐藤";names[1] = "鈴木";names[2] = "高橋";

配列の要素数は、Lengthで取得できます。

Console.WriteLine(names.Length);

配列は、作成時に要素数が固定される点が特徴です。

7-2. Listの基本的な使い方

List<T>は、要素を追加したり削除したりできるコレクションです。

using System.Collections.Generic;

List<string> names = new List<string>();

names.Add("佐藤");names.Add("鈴木");names.Add("高橋");

初期値を指定して作成することもできます。

List<int> scores = new List<int> { 80, 90, 70 };

新しい形式では、次のように簡潔に書くこともできます。

List<int> scores = new() { 80, 90, 70 };

要素の取得にはインデックスを使います。

Console.WriteLine(scores[0]);

要素の削除にはRemoveを使います。

scores.Remove(90);

指定した位置の要素を削除する場合は、RemoveAtを使用します。

scores.RemoveAt(0);

要素数はCountで取得します。

Console.WriteLine(scores.Count);

7-3. 配列とListの違い

配列とListの主な違いは、要素数を変更できるかどうかです。

配列は、作成時に要素数が決まります。

int[] numbers = new int[3];

Listは、あとから要素を追加・削除できます。

List<int> numbers = new List<int>();

numbers.Add(10);numbers.Add(20);numbers.Add(30);numbers.Add(40);

要素数が固定されているデータには配列、増減する可能性があるデータにはListが向いています。

配列の要素数はLengthListの要素数はCountで取得する点にも注意しましょう。

int[] array = { 1, 2, 3 };List<int> list = new List<int> { 1, 2, 3 };

Console.WriteLine(array.Length);Console.WriteLine(list.Count);

7-4. foreachで要素を取り出す方法

配列やListの全要素を順番に処理するには、foreach文を使います。

int[] scores = { 80, 90, 70 };

foreach (int score in scores){Console.WriteLine(score);}

Listでも同じように利用できます。

List<string> names = new List<string>{"佐藤","鈴木","高橋"};

foreach (string name in names){Console.WriteLine(name);}

合計値を求める例は次のとおりです。

int[] prices = { 100, 200, 300 };int total = 0;

foreach (int price in prices){total += price;}

Console.WriteLine($"合計:{total}円");

インデックスが必要ない処理では、for文よりもforeach文のほうが簡潔に書けます。

7-5. コレクション操作でよくあるエラー

配列やListでは、存在しないインデックスを指定するとエラーになります。

int[] numbers = { 10, 20, 30 };

// Console.WriteLine(numbers[3]);

この配列で使用できるインデックスは、012です。要素数が3でも、最後のインデックスは2になります。

for文で配列を処理するときは、条件に<を使います。

for (int i = 0; i < numbers.Length; i++){Console.WriteLine(numbers[i]);}

次のように<=を使うと、最後に範囲外のインデックスへアクセスします。

// for (int i = 0; i <= numbers.Length; i++)

また、foreachで処理している最中に、同じListの要素を追加・削除すると例外が発生する場合があります。

List<int> numbers = new List<int> { 1, 2, 3 };

// foreach (int number in numbers)// {// numbers.Remove(number);// }

削除が必要な場合は、後ろからfor文で処理するなど、コレクションの変更方法を工夫します。

for (int i = numbers.Count - 1; i >= 0; i--){if (numbers[i] % 2 == 1){numbers.RemoveAt(i);}}

8. C#のメソッド文法

メソッドは、複数の処理をまとめ、名前を付けたものです。処理をメソッドとして分けると、コードを再利用しやすくなります。

8-1. メソッドとは

同じ処理を何度も書くと、コードが長くなり、修正も難しくなります。

Console.WriteLine("こんにちは");Console.WriteLine("こんにちは");Console.WriteLine("こんにちは");

処理をメソッドにまとめると、次のように呼び出せます。

static void SayHello(){Console.WriteLine("こんにちは");}

SayHello();SayHello();SayHello();

メソッドには、処理内容がわかる名前を付けます。

DisplayUserName();CalculateTotalPrice();SaveData();

一般的に、C#のメソッド名にはパスカルケースを使います。

8-2. メソッドの定義と呼び出し

メソッドを作成することを「定義」、使用することを「呼び出し」といいます。

static void ShowMessage(){Console.WriteLine("メッセージを表示しました");}

メソッドは、名前の後ろに丸括弧を付けて呼び出します。

ShowMessage();

クラス全体では、次のように記述できます。

class Program{static void Main(string[] args){ShowMessage();}

static void ShowMessage(){Console.WriteLine("メッセージを表示しました");}

}

Mainメソッドから直接呼び出すメソッドをstaticにすると、インスタンスを作成せずに利用できます。

8-3. 引数と戻り値

メソッドへ渡す値を「引数」といいます。

static void Greet(string name){Console.WriteLine($"こんにちは、{name}さん");}

呼び出すときに、具体的な値を渡します。

Greet("佐藤");Greet("鈴木");

複数の引数を受け取ることも可能です。

static void Introduce(string name, int age){Console.WriteLine($"私は{name}です。{age}歳です。");}

Introduce("田中", 25);

メソッドから呼び出し元へ返す値を「戻り値」といいます。

static int Add(int a, int b){return a + b;}

戻り値を変数に代入できます。

int result = Add(10, 20);Console.WriteLine(result);

returnが実行されると、そのメソッドの処理は終了します。

8-4. voidの意味

voidは、そのメソッドが値を返さないことを表します。

static void ShowMessage(){Console.WriteLine("処理を実行しました");}

値を返すメソッドでは、voidの代わりに戻り値の型を書きます。

static int GetNumber(){return 100;}

文字列を返す場合はstringです。

static string GetUserName(){return "佐藤";}

真偽値を返す場合はboolです。

static bool IsAdult(int age){return age >= 18;}

画面への表示やデータの保存など、処理だけを実行するメソッドではvoidがよく使われます。

8-5. メソッドを使うメリット

メソッドを使う主なメリットは、処理を再利用できることです。

static int CalculateTaxIncludedPrice(int price){return (int)(price * 1.1);}

Console.WriteLine(CalculateTaxIncludedPrice(1000));Console.WriteLine(CalculateTaxIncludedPrice(2000));

計算方法を変更する場合も、メソッド内を修正するだけで済みます。

また、長い処理を複数のメソッドへ分割すると、プログラムの流れがわかりやすくなります。

static void Main(string[] args){ShowMenu();ReadInput();SaveResult();}

メソッド名を適切に付ければ、コメントがなくても何をしているのか理解しやすくなります。テストや不具合調査がしやすくなることも、メソッドを利用する重要なメリットです。

9. C#のクラスとオブジェクト指向の基本

C#はオブジェクト指向プログラミング言語です。クラスを使ってデータと処理をまとめ、プログラムを構成します。

9-1. クラスとは

クラスは、オブジェクトを作成するための設計図です。

たとえば、人物を表すPersonクラスは次のように作成できます。

class Person{public string Name { get; set; } = "";public int Age { get; set; }

public void Introduce(){Console.WriteLine($"私は{Name}です。{Age}歳です。");}

}

このクラスには、名前と年齢を保存するプロパティと、自己紹介を表示するメソッドがあります。

クラスを使うと、関連するデータと処理を一つにまとめられます。ユーザー、商品、注文、社員など、プログラムで扱う対象をクラスとして表現できます。

9-2. インスタンスとは

クラスをもとに実際に作成したオブジェクトを、インスタンスといいます。

Person person = new Person();

作成したインスタンスには、値を設定できます。

person.Name = "佐藤";person.Age = 30;

メソッドも呼び出せます。

person.Introduce();

同じクラスから複数のインスタンスを作成できます。

Person person1 = new Person();person1.Name = "佐藤";person1.Age = 30;

Person person2 = new Person();person2.Name = "鈴木";person2.Age = 25;

person1.Introduce();person2.Introduce();

クラスが設計図、インスタンスが設計図から作られた実物だと考えると理解しやすくなります。

9-3. フィールドとプロパティ

フィールドは、クラス内でデータを保持する変数です。

class Person{public string name = "";}

プロパティもデータを保持するために使われますが、値の取得や設定を管理しやすい仕組みを持っています。

class Person{public string Name { get; set; } = "";}

getは値の取得、setは値の設定を表します。

Person person = new Person();

person.Name = "佐藤"; // setConsole.WriteLine(person.Name); // get

値を外部から変更させたくない場合は、setの公開範囲を制限できます。

class Person{public string Name { get; private set; } = "";

public void ChangeName(string newName){Name = newName;}

}

一般的なC#のクラス設計では、外部へ公開するデータにはフィールドよりプロパティがよく使われます。

9-4. コンストラクタの基本

コンストラクタは、インスタンスを作成するときに実行される特別な処理です。クラス名と同じ名前で定義し、戻り値の型は書きません。

class Person{public string Name { get; set; }public int Age { get; set; }

public Person(string name, int age){Name = name;Age = age;}

}

インスタンスを作成するときに、必要な値を渡します。

Person person = new Person("佐藤", 30);

Console.WriteLine(person.Name);Console.WriteLine(person.Age);

コンストラクタを使うと、インスタンスの作成時に必要な初期値を設定できます。

引数の異なるコンストラクタを複数定義することも可能です。

class Person{public string Name { get; set; }public int Age { get; set; }

public Person(){Name = "未設定";}public Person(string name, int age){Name = name;Age = age;}

}

9-5. public・privateなどアクセス修飾子の使い方

アクセス修飾子は、クラス、メソッド、プロパティなどを、どこから利用できるか指定するためのキーワードです。

publicを付けると、ほかのクラスから利用できます。

public void Introduce(){Console.WriteLine("自己紹介");}

privateを付けると、そのクラスの内部からだけ利用できます。

private void Validate(){Console.WriteLine("入力を確認します");}

例として、残高を外部から自由に変更できないクラスを考えてみましょう。

class BankAccount{public int Balance { get; private set; }

public void Deposit(int amount){if (amount &gt; 0){Balance += amount;}}

}

外部からはDepositメソッドを通して残高を増やします。

BankAccount account = new BankAccount();account.Deposit(1000);

Console.WriteLine(account.Balance);

アクセス範囲を適切に制限することで、不正な値の設定や意図しない操作を防ぎやすくなります。

10. C#の例外処理

プログラムの実行中には、数値変換の失敗、存在しないファイルへのアクセス、範囲外のインデックス指定など、さまざまな問題が発生します。こうした実行時の異常を扱う仕組みが例外処理です。

10-1. 例外とは

例外とは、プログラムの実行中に発生する通常とは異なる状態です。

たとえば、数値に変換できない文字列をint.Parseへ渡すと例外が発生します。

string text = "abc";int number = int.Parse(text);

また、配列の範囲外へアクセスした場合も例外になります。

int[] numbers = { 10, 20, 30 };

// Console.WriteLine(numbers[5]);

例外が処理されていない場合、プログラムはその場所で停止します。想定できる例外を適切に処理すると、エラーメッセージを表示したり、別の処理を実行したりできます。

10-2. try-catch文の基本構文

例外が発生する可能性のある処理は、tryブロックに記述します。例外発生時の処理は、catchブロックに記述します。

try{string text = "abc";int number = int.Parse(text);

Console.WriteLine(number);

}catch{Console.WriteLine("数値に変換できませんでした");}

発生した例外の情報を受け取ることもできます。

try{int number = int.Parse("abc");}catch (FormatException ex){Console.WriteLine($"形式が正しくありません:{ex.Message}");}

特定の例外を指定すると、例外の種類に応じて処理を分けられます。

try{int[] numbers = { 10, 20, 30 };Console.WriteLine(numbers[5]);}catch (IndexOutOfRangeException){Console.WriteLine("配列の範囲外です");}

10-3. finallyの使い方

finallyブロックには、例外が発生してもしなくても実行したい処理を書きます。

try{Console.WriteLine("処理を開始します");int number = int.Parse("100");}catch (FormatException){Console.WriteLine("変換に失敗しました");}finally{Console.WriteLine("処理を終了します");}

finallyは、ファイルや通信など、使用後に解放が必要なリソースを扱う場面で利用されます。

ただし、C#ではusing文などを利用してリソースを自動的に解放できる場合もあります。初心者の段階では、「finallyは成功・失敗にかかわらず実行される」と理解しておきましょう。

10-4. よくある例外の種類

C#でよく目にする例外には、次のようなものがあります。

NullReferenceException

nullになっている変数を通して、プロパティやメソッドへアクセスした場合に発生します。

string? name = null;

// Console.WriteLine(name.Length);

IndexOutOfRangeException

配列の範囲外へアクセスした場合に発生します。

int[] numbers = { 1, 2, 3 };

// Console.WriteLine(numbers[3]);

ArgumentOutOfRangeException

メソッドへ許容範囲外の値を渡した場合などに発生します。

FormatException

文字列の形式が、変換先の型に対応していない場合に発生します。

// int number = int.Parse("abc");

DivideByZeroException

整数を0で割った場合に発生します。

int divisor = 0;

// int result = 10 / divisor;

例外名から、問題の種類をある程度推測できます。

10-5. エラーを読み解くポイント

エラーが表示されたら、まずエラーメッセージを確認しましょう。英語のメッセージでも、例外名、ファイル名、行番号を見ると原因を絞り込めます。

特に確認したい情報は次のとおりです。

  • エラーや例外の種類

  • エラーメッセージ

  • 問題が発生したファイル

  • 問題が発生した行番号

  • 呼び出し元を示すスタックトレース

たとえば、NullReferenceExceptionが表示された場合は、その行で使っている変数のどれかがnullになっていないか確認します。

エラーが発生した行だけでなく、その変数に値を代入している場所までさかのぼって調べることが重要です。エラーメッセージをそのまま検索することも、原因を調べる有効な方法です。

11. C#文法で初心者がつまずきやすいポイント

C#を学び始めたばかりの時期には、セミコロン、文字の大小、データ型、null、変数の有効範囲などでエラーが起こりやすくなります。

11-1. セミコロンの付け忘れ

C#では、多くの命令の末尾にセミコロンが必要です。

int age = 20;Console.WriteLine(age);

セミコロンを忘れると、コンパイルエラーになります。

// int age = 20// Console.WriteLine(age);

ただし、クラス、メソッド、if文、for文などの波括弧の直後には、通常セミコロンを付けません。

if (age >= 18){Console.WriteLine("成人です");}

一方、do while文では、末尾にセミコロンが必要です。

do{age++;}while (age < 30);

エラーが別の行に表示される場合もあるため、直前の行にセミコロンが付いているか確認しましょう。

11-2. 大文字・小文字の違い

C#では、大文字と小文字が区別されます。

string name = "佐藤";string Name = "鈴木";

nameNameは別の変数です。

標準機能の名前でも、大文字・小文字を正しく書く必要があります。

Console.WriteLine("正しい書き方");

次のような記述は正しくありません。

// console.writeline("誤った書き方");

C#では、一般的にクラス名、メソッド名、プロパティ名にパスカルケースを使います。

CalculateTotalPrice();

ローカル変数や引数には、先頭を小文字にするキャメルケースを使います。

int totalPrice = 1000;

11-3. 型の不一致

C#では、変数の型に合わない値を代入できません。

int age = 20;

// age = "20";

文字列の"20"と数値の20は異なるデータです。文字列を数値として使うには、型変換が必要です。

string text = "20";int age = int.Parse(text);

メソッドの引数や戻り値でも、型を合わせる必要があります。

static int Add(int a, int b){return a + b;}

次のように文字列を渡すことはできません。

// int result = Add("10", "20");

型エラーが発生した場合は、変数の宣言、代入する値、メソッドの引数、戻り値の型を確認しましょう。

11-4. null参照エラー

nullは、参照先が存在しない状態を表します。

string? name = null;

nullの変数からプロパティやメソッドへアクセスすると、NullReferenceExceptionが発生する可能性があります。

// Console.WriteLine(name.Length);

アクセスする前にnullを確認できます。

if (name != null){Console.WriteLine(name.Length);}

null条件演算子?.を使う方法もあります。

Console.WriteLine(name?.Length);

値がnullだった場合の代替値には、null合体演算子??を使えます。

string displayName = name ?? "名前未設定";

Console.WriteLine(displayName);

nullが発生し得る変数と、必ず値が入る変数を意識して区別することが大切です。

11-5. スコープの理解不足

スコープとは、変数などを利用できる範囲です。

波括弧の中で宣言した変数は、基本的にその波括弧の中だけで利用できます。

if (true){string message = "こんにちは";Console.WriteLine(message);}

// Console.WriteLine(message);

messageif文の外では利用できません。

メソッド内で宣言したローカル変数も、そのメソッド内だけで有効です。

static void MethodA(){int number = 10;}

static void MethodB(){// Console.WriteLine(number);}

複数の処理で値を共有したい場合は、必要な範囲に合わせて、引数、戻り値、フィールド、プロパティなどを利用します。

変数の有効範囲を必要以上に広げないことも、読みやすく安全なコードを書くポイントです。

12. C#文法を効率よく覚える学習手順

C#文法は、すべてを一度に暗記しようとするより、基本構文を使って小さなプログラムを作りながら覚えるほうが効率的です。

12-1. まず覚えるべき基本構文

C#初心者は、次の順番で学ぶと理解しやすくなります。

  1. Console.WriteLineによる出力

  2. 変数とデータ型

  3. 算術演算子と比較演算子

  4. if文による条件分岐

  5. for文やforeach文による繰り返し

  6. 配列とList

  7. メソッド

  8. クラスとインスタンス

  9. 例外処理

最初から高度なオブジェクト指向や非同期処理を理解する必要はありません。

まずは、次のような短いコードを自分で書ける状態を目指しましょう。

int score = 75;

if (score >= 60){Console.WriteLine("合格です");}else{Console.WriteLine("不合格です");}

12-2. サンプルコードを書いて理解する

解説を読むだけでは、文法を使えるようになりにくいものです。サンプルコードを実際に入力し、実行結果を確認しましょう。

さらに、サンプルの一部を変更して、結果がどう変わるか試すと理解が深まります。

for (int i = 1; i <= 5; i++){Console.WriteLine(i);}

このコードを入力したあと、次のような変更を試してみましょう。

  • 開始値を0にする

  • 終了条件を10にする

  • i++i += 2にする

  • 数字ではなく計算結果を表示する

たとえば、2の倍数を表示するコードは次のようになります。

for (int i = 2; i <= 10; i += 2){Console.WriteLine(i);}

コードをコピーするだけでなく、自分で変更し、エラーも経験することが重要です。

12-3. 小さなプログラムを作って練習する

基本文法を学んだら、複数の構文を組み合わせた小さなプログラムを作りましょう。

初心者向けの練習課題には、次のようなものがあります。

  • 2つの数値を入力して計算する電卓

  • 点数から評価を判定するプログラム

  • 1から100までの合計を求めるプログラム

  • 商品価格の合計を求めるプログラム

  • 名前を一覧表示するプログラム

  • 数当てゲーム

  • 簡単なメモ管理プログラム

たとえば、配列内の点数から平均値を求めるプログラムは次のように作れます。

int[] scores = { 80, 75, 90, 85 };int total = 0;

foreach (int score in scores){total += score;}

double average = (double)total / scores.Length;

Console.WriteLine($"合計点:{total}");Console.WriteLine($"平均点:{average}");

小さくても、最初から最後まで自分で完成させる経験が、C#文法の定着につながります。

12-4. エラーを調べながら学ぶ

プログラミング学習では、エラーを完全に避けることはできません。エラーは失敗ではなく、コードの問題点を教えてくれる情報です。

エラーが発生したら、次の順番で確認します。

  1. エラーが発生した行を見る

  2. エラーメッセージを読む

  3. セミコロンや波括弧を確認する

  4. 変数名の大文字・小文字を確認する

  5. データ型を確認する

  6. 直前に変更したコードを確認する

  7. エラーメッセージを検索する

複数の変更を一度に加えると、原因を特定しにくくなります。コードは少しずつ書き、その都度実行する習慣を付けましょう。

また、エラーが解決したら、原因と修正内容を簡単に記録しておくと、同じ問題が発生したときに役立ちます。

12-5. 次に学ぶべきC#の応用文法

基本文法を理解したら、次の内容へ進みましょう。

  • 継承

  • インターフェース

  • 抽象クラス

  • ジェネリック

  • デリゲート

  • ラムダ式

  • LINQ

  • 例外処理の設計

  • ファイル操作

  • 非同期処理

  • nullable参照型

  • レコード

  • パターンマッチング

  • 単体テスト

特にLINQを学ぶと、配列やListの検索、絞り込み、並べ替えなどを簡潔に書けるようになります。

using System.Linq;

List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };

var evenNumbers = numbers.Where(number => number % 2 == 0);

foreach (int number in evenNumbers){Console.WriteLine(number);}

ただし、応用文法へ急ぐ必要はありません。変数、条件分岐、繰り返し、メソッド、クラスといった基本を使えることが、応用機能を理解する土台になります。

まとめ

C#(csharp)の文法を学ぶときは、最初にプログラムの基本構造を理解し、変数、データ型、演算子、条件分岐、繰り返し処理の順番で進めると効率的です。

配列やListで複数のデータを扱い、メソッドで処理を整理できるようになったら、クラスやインスタンスなどのオブジェクト指向へ進みましょう。プログラム実行中の問題に対応するため、例外処理やエラーメッセージの読み方も重要です。

C#文法は、解説を読むだけでなく、コードを書いて実行することで身につきます。サンプルコードの値や条件を変更し、結果がどのように変わるか確認してみてください。

最初からすべてを暗記する必要はありません。わからない文法をその都度調べながら、小さなプログラムを繰り返し作ることが、C#を習得する近道です。