C#の宣言とは?変数・クラス・メソッドの書き方を初心者向けに解説

はじめに

C#でプログラムを書くときは、変数やクラス、メソッドなどを使用する前に、それらの名前や型、役割をコード上に記述します。この記述が「宣言」です。

たとえば、整数を保存する変数を用意する場合は、次のように書きます。

C#
int age;

このコードは、「ageという名前で、int型の値を扱う変数を用意する」とC#に伝えています。

宣言はC#プログラミングの基本です。しかし、宣言・初期化・代入・インスタンス生成など、似た場面で使われる言葉が多いため、初心者は混同しやすい傾向があります。

この記事では、C#の宣言について、変数・クラス・メソッドの書き方を中心に解説します。アクセス修飾子や配列、プロパティ、インターフェイスなどの宣言方法も、サンプルコードを使いながら確認していきましょう。

1. C#の「宣言」とは何か

1-1. 宣言とは「名前・型・使い方をプログラムに知らせること」

C#における宣言とは、プログラムで使用する要素の名前や型、利用方法などをコンパイラに知らせる記述です。

たとえば、次のコードは変数の宣言です。

C#
int score;

この宣言には、次の情報が含まれています。

  • int:変数が扱うデータの型

  • score:変数の名前

  • ;:文の終わり

クラスを宣言するときは、次のように記述します。

C#
class Player
{
}

メソッドの宣言は次のとおりです。

C#
void Start()
{
}

このように、宣言する対象によって構文は異なりますが、「プログラム内で何をどのように使うのかを示す」という役割は共通しています。

1-2. 宣言と定義・初期化・代入の違い

宣言と似た言葉として、定義・初期化・代入があります。それぞれの違いを理解しておくことが大切です。

宣言

名前や型をプログラムに知らせることです。

C#
int count;

ここでは、countというint型の変数を宣言しています。

初期化

変数を宣言するときに、最初の値を設定することです。

C#
int count = 0;

このコードでは、countを宣言すると同時に、初期値として0を設定しています。

代入

すでに宣言されている変数に値を設定することです。

C#
count = 10;

変数countが事前に宣言されていれば、このコードによって値が10に変更されます。

定義

定義は、対象の具体的な内容や処理を記述することを指します。

たとえば、メソッド名や戻り値だけでなく、実際の処理まで記述したコードはメソッドの定義と呼ばれます。

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

ただし、C#の解説では「宣言」と「定義」が厳密に区別されず、クラス宣言やメソッド宣言という表現の中に具体的な内容まで含める場合があります。

1-3. C#で宣言が必要になる主な場面

C#では、主に次のような要素を扱うときに宣言が必要です。

  • 変数

  • 定数

  • フィールド

  • プロパティ

  • メソッド

  • クラス

  • 構造体

  • 列挙型

  • インターフェイス

  • デリゲート

  • 名前空間

たとえば、ユーザーの年齢を保存するには変数を宣言します。

C#
int userAge;

ユーザーの情報や操作をまとめて管理したい場合は、クラスを宣言します。

C#
class User
{
}

複数の場所から呼び出せる処理を作成したい場合は、メソッドを宣言します。

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

プログラムの規模が大きくなるほど、適切な宣言によってコードの構造や役割を明確にすることが重要になります。

1-4. 初心者が混同しやすい「宣言」の考え方

初心者が混同しやすいのは、「宣言しただけで使用できるのか」という点です。

次のコードでは、変数を宣言していますが、値は設定していません。

C#
int number;

ローカル変数は、値を代入する前に読み取ることができません。

C#
int number;
Console.WriteLine(number); // コンパイルエラー

次のように初期化すれば使用できます。

C#
int number = 10;
Console.WriteLine(number);

一方、クラスのフィールドは、明示的に値を設定しなくても型に応じた既定値で初期化されます。

C#
class Sample
{
private int number; // 既定値は0
}

宣言する対象や場所によって初期値の扱いが異なるため、「宣言したら必ず値が使える」と考えないようにしましょう。

2. C#の変数宣言の基本

2-1. 変数宣言の基本構文

C#の変数宣言は、基本的に次の形式で記述します。

C#
データ型 変数名;

整数を扱う変数であれば、次のように宣言します。

C#
int age;

文字列を扱う場合は、string型を使用します。

C#
string name;

小数を扱う場合は、用途に応じてdouble型やdecimal型などを使用します。

C#
double height;
decimal price;

C#では、変数が扱える値は宣言された型によって決まります。そのため、保存したいデータに適した型を選ぶ必要があります。

2-2. 型を指定して変数を宣言する方法

C#でよく使われる型には、次のようなものがあります。

C#
int count;
long population;
float speed;
double average;
decimal price;
bool isActive;
char grade;
string message;

それぞれの用途は次のとおりです。

主な用途値の例
int整数100
long大きな整数10000000000L
float単精度の小数1.5f
double小数3.14
decimal金額など高精度な小数1200.50m
bool真偽値truefalse
char1文字'A'
string文字列"Hello"

型を明示して宣言すると、その変数が何を扱うものなのかをコードから判断しやすくなります。

C#
int itemCount = 3;
decimal totalPrice = 1500.00m;
bool isCompleted = false;

2-3. 宣言と同時に初期化する方法

変数は、宣言と同時に初期値を設定できます。

C#
int score = 100;
string playerName = "田中";
bool isGameOver = false;

この書き方では、変数の宣言と初期化を1つの文で行っています。

宣言と初期化を分けて書くことも可能です。

C#
int score;
score = 100;

ただし、初期値が決まっている場合は、宣言と同時に初期化するほうが、未代入のまま使用するミスを防ぎやすくなります。

同じ型の変数を複数宣言することもできます。

C#
int x = 10, y = 20;

しかし、変数ごとの役割を分かりやすくするため、通常は1行につき1つの変数を宣言する書き方が読みやすいでしょう。

C#
int x = 10;
int y = 20;

2-4. varを使った型推論による宣言

C#では、varを使ってローカル変数を宣言できます。

C#
var age = 20;
var name = "佐藤";
var price = 980.5;

varを使用すると、右辺の値からコンパイラが型を推論します。

上記のコードは、実質的に次の宣言と同じ型になります。

C#
int age = 20;
string name = "佐藤";
double price = 980.5;

varは動的な型を意味するものではありません。一度型が決まると、異なる型の値は代入できません。

C#
var count = 10;
count = 20; // 問題なし
// count = "20"; // コンパイルエラー

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

C#
// var value; // コンパイルエラー
var value = 100;

型が右辺から明確に分かる場合には、varを使うことでコードを簡潔にできます。

C#
var users = new List<string>();

一方、数値リテラルなどは型が分かりにくくなる場合があります。可読性を考え、型を明示するかどうかを判断しましょう。

2-5. const・readonlyによる定数や読み取り専用フィールドの宣言

変更しない値を扱う場合は、constreadonlyを使用できます。

constによる定数宣言

constは、コンパイル時に値が確定する定数を宣言するときに使用します。

C#
const double TaxRate = 0.1;
const int MaxUsers = 100;
const string AppName = "SampleApp";

constで宣言した値は、後から変更できません。

C#
const int MaxCount = 10;
// MaxCount = 20; // コンパイルエラー

ローカル定数として使うことも、クラスのメンバーとして使うこともできます。クラス内のconstは、実質的に型そのものに属する値として扱われます。

readonlyによる読み取り専用フィールド宣言

readonlyは、フィールドの宣言時またはコンストラクター内で値を設定し、その後は変更させたくない場合に使用します。

C#
class User
{
private readonly int id;

public User(int id)
{
this.id = id;
}
}

constはコンパイル時に値が決まるものに向いています。readonlyは、インスタンス生成時など実行時に値を決めたい場合に向いています。

C#
class Settings
{
public const int MaxRetryCount = 3;
public readonly DateTime CreatedAt = DateTime.Now;
}

2-6. 変数宣言でよくあるエラーと対処法

初期化せずに使用する

C#
int total;
// Console.WriteLine(total); // エラー

値を読み取る前に初期化します。

C#
int total = 0;
Console.WriteLine(total);

型が一致していない

C#
// int age = "20"; // エラー

文字列を整数に変換する場合は、int.Parseint.TryParseなどを使用します。

C#
string input = "20";
int age = int.Parse(input);

安全に変換するなら、TryParseが便利です。

C#
string input = "20";

if (int.TryParse(input, out int age))
{
Console.WriteLine(age);
}

同じスコープで同じ名前を宣言する

C#
int count = 1;
// int count = 2; // エラー

変数名を変更するか、既存の変数に代入します。

C#
int count = 1;
count = 2;

変数名に使えない名前を指定する

数字から始まる名前や、一部の予約語は通常の変数名として使用できません。

C#
// int 1count = 10;
// string class = "A";

意味が伝わる有効な名前を付けます。

C#
int itemCount = 10;
string className = "A";

3. C#のクラス宣言の書き方

3-1. クラス宣言の基本構文

クラスは、データと処理をまとめるための設計図です。基本構文は次のとおりです。

C#
アクセス修飾子 class クラス名
{
// フィールド、プロパティ、メソッドなど
}

簡単なクラス宣言は次のようになります。

C#
class Person
{
}

このコードでは、Personという名前のクラスを宣言しています。

クラス名には、通常、各単語の先頭を大文字にするPascalCaseを使用します。

C#
class UserAccount
{
}

3-2. classキーワードの使い方

classキーワードは、その宣言がクラスであることを示します。

C#
class Product
{
}

クラスには、関連するデータや処理をまとめられます。

C#
class Product
{
public string Name { get; set; } = "";
public decimal Price { get; set; }

public void ShowInfo()
{
Console.WriteLine($"{Name}: {Price}円");
}
}

このProductクラスには、商品名と価格を表すプロパティ、商品情報を表示するメソッドが含まれています。

3-3. アクセス修飾子を使ったクラス宣言

クラスにはアクセス修飾子を指定できます。

C#
public class Product
{
}

名前空間直下に宣言するクラスで主に使用できるアクセス修飾子は、publicinternalです。

C#
public class PublicClass
{
}

internal class InternalClass
{
}

publicクラスは、参照可能な別のプロジェクトやアセンブリからも利用できます。

internalクラスは、基本的に同じアセンブリ内からのみ利用できます。名前空間直下のクラスでアクセス修飾子を省略した場合は、internalとして扱われます。

C#
class Sample
{
// internal class Sample と同等
}

クラスの中に宣言する入れ子クラスでは、privateprotectedなども利用できます。

C#
public class Outer
{
private class Inner
{
}
}

3-4. クラス内でフィールド・プロパティ・メソッドを宣言する方法

クラスの中には、フィールド・プロパティ・メソッドなどを宣言できます。

C#
public class User
{
private int age;

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

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

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

  • age:クラス内部でデータを保持するフィールド

  • Name:外部とのデータの受け渡しに使うプロパティ

  • Introduce:処理をまとめたメソッド

フィールドを外部へ直接公開するより、プロパティを通して扱う設計が一般的です。

3-5. クラス宣言の具体例

次のコードは、商品の名前と価格を管理するクラスの例です。

C#
public class Product
{
public string Name { get; set; }
public decimal Price { get; set; }

public Product(string name, decimal price)
{
Name = name;
Price = price;
}

public void ShowDetails()
{
Console.WriteLine($"商品名: {Name}");
Console.WriteLine($"価格: {Price}円");
}
}

このクラスからオブジェクトを生成して使用するコードは次のとおりです。

C#
Product product = new Product("キーボード", 5000m);
product.ShowDetails();

クラス宣言は設計図を作る処理であり、newを使ったコードは、その設計図から実際のインスタンスを生成する処理です。

4. C#のメソッド宣言の書き方

4-1. メソッド宣言の基本構文

メソッドは、特定の処理をひとまとまりにしたものです。基本構文は次のとおりです。

C#
アクセス修飾子 戻り値の型 メソッド名(引数)
{
// 処理
}

たとえば、2つの整数を加算するメソッドは次のように宣言できます。

C#
public int Add(int a, int b)
{
return a + b;
}

各部分の意味は次のとおりです。

  • public:アクセス修飾子

  • int:戻り値の型

  • Add:メソッド名

  • int a, int b:引数

  • return a + b;:呼び出し元へ値を返す処理

4-2. 戻り値の型を指定する方法

値を返すメソッドでは、返す値の型をメソッド名の前に記述します。

C#
public int GetNumber()
{
return 10;
}

文字列を返す場合は、戻り値の型をstringにします。

C#
public string GetMessage()
{
return "こんにちは";
}

真偽値を返す場合は、boolを指定します。

C#
public bool IsAdult(int age)
{
return age >= 18;
}

宣言した戻り値の型と、returnで返す値の型は一致している必要があります。

C#
public int GetScore()
{
return 100;
}

次のように異なる型を返すことはできません。

C#
public int GetScore()
{
// return "100"; // コンパイルエラー
return 100;
}

4-3. 引数を持つメソッドの宣言

メソッドに値を渡したい場合は、引数を宣言します。

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

呼び出すときは、引数に対応する値を渡します。

C#
Greet("山田");

複数の引数を宣言する場合は、カンマで区切ります。

C#
public int Multiply(int x, int y)
{
return x * y;
}

呼び出し例は次のとおりです。

C#
int result = Multiply(3, 5);
Console.WriteLine(result);

引数には、それぞれ型と名前が必要です。

C#
public void ShowUser(string name, int age)
{
Console.WriteLine($"{name}さんは{age}歳です");
}

4-4. voidを使った戻り値なしメソッドの宣言

呼び出し元へ値を返さないメソッドでは、戻り値の型としてvoidを指定します。

C#
public void ShowMessage()
{
Console.WriteLine("処理を開始します");
}

voidメソッドは、画面への表示やデータの更新など、戻り値を必要としない処理に使用されます。

C#
public void UpdateName(string newName)
{
Name = newName;
}

voidメソッドでも、処理を途中で終了するために引数なしのreturnを使用できます。

C#
public void PrintPositiveNumber(int number)
{
if (number <= 0)
{
return;
}

Console.WriteLine(number);
}

ただし、voidメソッドから値を返すことはできません。

4-5. staticメソッドとインスタンスメソッドの宣言

staticを付けたメソッドは、クラスそのものに属する静的メソッドです。

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

静的メソッドは、通常、インスタンスを生成せずにクラス名から呼び出します。

C#
int result = Calculator.Add(10, 20);

staticを付けないメソッドは、インスタンスメソッドです。

C#
public class Calculator
{
public int Add(int a, int b)
{
return a + b;
}
}

呼び出すにはインスタンスを生成します。

C#
Calculator calculator = new Calculator();
int result = calculator.Add(10, 20);

インスタンスごとの状態を利用する処理にはインスタンスメソッドが適しています。一方、特定のインスタンスの状態に依存しない処理には、静的メソッドが適しています。

4-6. メソッド宣言の具体例

次のコードは、商品の税込価格を計算するメソッドの例です。

C#
public class PriceCalculator
{
public decimal CalculateTaxIncludedPrice(decimal price, decimal taxRate)
{
return price * (1 + taxRate);
}
}

使用例は次のとおりです。

C#
PriceCalculator calculator = new PriceCalculator();

decimal totalPrice = calculator.CalculateTaxIncludedPrice(1000m, 0.1m);

Console.WriteLine(totalPrice);

同じ処理を静的メソッドとして宣言することもできます。

C#
public class PriceCalculator
{
public static decimal CalculateTaxIncludedPrice(
decimal price,
decimal taxRate)
{
return price * (1 + taxRate);
}
}

この場合は、インスタンス生成が不要です。

C#
decimal totalPrice =
PriceCalculator.CalculateTaxIncludedPrice(1000m, 0.1m);

5. C#で使われるその他の宣言

5-1. プロパティ宣言

プロパティは、クラスが保持するデータを外部から取得・設定するための仕組みです。

C#
public string Name { get; set; } = "";

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

読み取り専用にしたい場合は、setを省略できます。

C#
public int Id { get; }

コンストラクターから値を設定する例は次のとおりです。

C#
public class User
{
public int Id { get; }

public User(int id)
{
Id = id;
}
}

外部からの変更を制限したい場合は、private setも使用できます。

C#
public string Name { get; private set; } = "";

5-2. フィールド宣言

フィールドは、クラスや構造体の内部でデータを保持する変数です。

C#
private int count;

初期値を設定して宣言することもできます。

C#
private int count = 0;
private string message = "未設定";

フィールドはインスタンスごとに保持されますが、staticを付けるとクラス全体で共有されます。

C#
private static int instanceCount;

一般的にはフィールドをprivateにし、必要なデータだけをプロパティやメソッドを通して公開します。

5-3. 配列宣言

配列は、同じ型の複数の値をまとめて扱うための仕組みです。

配列の基本的な宣言は次のとおりです。

C#
int[] numbers;

要素数を指定して生成する場合は、newを使用します。

C#
int[] numbers = new int[3];

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

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

文字列の配列は次のように宣言します。

C#
string[] names = { "田中", "佐藤", "鈴木" };

配列の各要素には、0から始まるインデックスを使ってアクセスします。

C#
Console.WriteLine(names[0]);

5-4. enum宣言

enumは、関連する定数をひとまとめにして表現する列挙型です。

C#
public enum DayOfWeekType
{
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday
}

使用例は次のとおりです。

C#
DayOfWeekType today = DayOfWeekType.Monday;

数値や文字列を直接扱うより、値の意味が分かりやすくなります。

C#
public enum OrderStatus
{
Pending,
Processing,
Shipped,
Completed,
Canceled
}
C#
OrderStatus status = OrderStatus.Processing;

各列挙子に数値を明示することもできます。

C#
public enum ErrorCode
{
None = 0,
NotFound = 404,
ServerError = 500
}

5-5. interface宣言

インターフェイスは、クラスが実装する機能の契約を宣言する仕組みです。

C#
public interface ILogger
{
void Log(string message);
}

インターフェイスを実装するクラスでは、宣言されたメンバーに対応する処理を記述します。

C#
public class ConsoleLogger : ILogger
{
public void Log(string message)
{
Console.WriteLine(message);
}
}

利用例は次のとおりです。

C#
ILogger logger = new ConsoleLogger();
logger.Log("処理を開始しました");

インターフェイスを利用すると、具体的な実装に強く依存しないコードを作りやすくなります。

5-6. namespace宣言

名前空間は、クラスやインターフェイスなどを分類し、名前の衝突を防ぐために使用します。

C#
namespace SampleApp.Models
{
public class User
{
}
}

ファイルスコープ形式では、次のように記述できます。

C#
namespace SampleApp.Models;

public class User
{
}

ファイルスコープ名前空間を使用すると、波かっこが不要になり、インデントを減らせます。

同じクラス名でも名前空間が異なれば、別の型として扱えます。

C#
namespace App.Customers
{
public class User
{
}
}

namespace App.Administrators
{
public class User
{
}
}

5-7. usingディレクティブによる名前空間の利用宣言

usingディレクティブを使用すると、名前空間を省略して型を記述できます。

C#
using System;
using System.Collections.Generic;

System.Collections.Genericusingで指定していれば、次のように書けます。

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

usingがない場合は、完全修飾名を記述します。

C#
System.Collections.Generic.List<string> names =
new System.Collections.Generic.List<string>();

別名を付けることもできます。

C#
using TextBuilder = System.Text.StringBuilder;
C#
TextBuilder builder = new TextBuilder();

なお、usingディレクティブは変数やクラスを宣言する構文ではありません。指定した名前空間内の型を簡潔に参照するための指示です。

6. 宣言時に使うアクセス修飾子とキーワード

6-1. public・private・protected・internalの違い

アクセス修飾子は、クラスやメンバーをどこから利用できるか指定するキーワードです。

public

どこからでもアクセスできるようにします。

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

private

宣言したクラスの内部からのみアクセスできます。

C#
public class User
{
private int age;
}

クラスメンバーのアクセス修飾子を省略すると、基本的にはprivateとして扱われます。

protected

宣言したクラスと、そのクラスを継承した派生クラスからアクセスできます。

C#
public class Animal
{
protected string name = "";
}

internal

同じアセンブリ内からアクセスできます。

C#
internal class InternalService
{
}

アクセス範囲は必要以上に広げず、外部へ公開する必要がないものはprivateinternalにすることが基本です。

6-2. staticの意味と使い方

staticは、メンバーが個々のインスタンスではなく、型そのものに属することを示します。

静的フィールドの例は次のとおりです。

C#
public class Counter
{
public static int TotalCount;
}

クラス名から直接アクセスできます。

C#
Counter.TotalCount++;

静的メソッドもインスタンスを生成せずに呼び出せます。

C#
public class MathHelper
{
public static int Square(int number)
{
return number * number;
}
}
C#
int result = MathHelper.Square(5);

クラス自体をstaticとして宣言することもできます。

C#
public static class MathHelper
{
public static int Square(int number)
{
return number * number;
}
}

静的クラスはインスタンスを生成できず、基本的に静的メンバーだけを持ちます。

6-3. abstract・virtual・overrideの使い方

これらのキーワードは、主にクラスの継承で使用します。

abstract

abstractは、派生クラスで具体的な処理を実装させたい場合に使用します。

C#
public abstract class Animal
{
public abstract void Speak();
}

抽象クラスは、そのままではインスタンスを生成できません。

C#
public class Dog : Animal
{
public override void Speak()
{
Console.WriteLine("ワン");
}
}

virtual

virtualは、基底クラスに標準の処理を用意しつつ、派生クラスによる上書きを許可します。

C#
public class Animal
{
public virtual void Speak()
{
Console.WriteLine("鳴き声");
}
}

override

overrideは、基底クラスのabstractメソッドやvirtualメソッドを上書きするときに使用します。

C#
public class Cat : Animal
{
public override void Speak()
{
Console.WriteLine("ニャー");
}
}

abstractは実装を派生クラスに任せたいとき、virtualは既定の実装を変更可能にしたいときに使います。

6-4. newキーワードを使ったインスタンス生成との違い

クラス宣言は、オブジェクトの設計図を作ることです。

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

これだけでは、具体的なユーザーオブジェクトは作成されていません。

newキーワードを使用すると、クラスからインスタンスを生成できます。

C#
User user = new User();

このコードには、変数宣言とインスタンス生成が含まれています。

  • User:変数の型

  • user:変数名

  • new User():インスタンス生成

プロパティに値を設定する場合は、次のように記述します。

C#
User user = new User();
user.Name = "山田";

オブジェクト初期化子を使うこともできます。

C#
User user = new User
{
Name = "山田"
};

宣言は名前や型を用意する処理、newはクラスをもとに実体を生成する処理と理解しましょう。

6-5. 宣言時のキーワードを正しく選ぶポイント

宣言に使うキーワードは、対象の役割を考えて選びます。

外部へ公開する必要があるメンバーにはpublicを使用します。

C#
public string Name { get; set; } = "";

クラス内部だけで使用するデータにはprivateを使用します。

C#
private int count;

インスタンスごとの状態に依存しない処理にはstaticを検討します。

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

変更しない固定値にはconstを使用します。

C#
public const int MaxCount = 100;

実行時に決定し、その後変更しないフィールドにはreadonlyを使用します。

C#
private readonly DateTime createdAt = DateTime.Now;

継承先で実装を変更させたいメソッドには、abstractvirtualを使用します。

キーワードを多く付ければよいわけではありません。対象をどこから使うのか、変更を許可するのか、インスタンスごとに保持するのかを考えることが重要です。

7. C#の宣言で初心者がつまずきやすいポイント

7-1. 宣言しただけでは値が使えないケース

メソッド内で宣言したローカル変数は、値が代入されるまで読み取れません。

C#
int score;
// Console.WriteLine(score); // エラー

次のように初期化してから使用します。

C#
int score = 0;
Console.WriteLine(score);

条件分岐の中でのみ代入する場合も注意が必要です。

C#
int score;
bool isSuccess = true;

if (isSuccess)
{
score = 100;
}

// Console.WriteLine(score); // 代入されない可能性があるためエラー

すべての経路で値が代入されるようにします。

C#
int score;
bool isSuccess = true;

if (isSuccess)
{
score = 100;
}
else
{
score = 0;
}

Console.WriteLine(score);

または、宣言時に既定の値を設定します。

C#
int score = 0;

7-2. 型が一致しないときのエラー

C#は静的型付け言語なので、変数の型と代入する値の型が適合している必要があります。

C#
int age = 20;
// age = "二十"; // エラー

文字列を数値として使用したい場合は変換します。

C#
string input = "20";

if (int.TryParse(input, out int age))
{
Console.WriteLine(age);
}
else
{
Console.WriteLine("整数に変換できません");
}

小数を整数に変換するときは、明示的なキャストが必要になる場合があります。

C#
double value = 10.8;
int number = (int)value;

この場合、小数部分は切り捨てられ、number10になります。型変換では、データが失われる可能性にも注意しましょう。

7-3. スコープ外の変数を使おうとするエラー

変数を使用できる範囲をスコープと呼びます。

C#
if (true)
{
int number = 10;
Console.WriteLine(number);
}

// Console.WriteLine(number); // エラー

numberifブロック内で宣言されているため、ブロックの外からは使用できません。

外側でも使いたい場合は、外側のスコープで宣言します。

C#
int number = 0;

if (true)
{
number = 10;
}

Console.WriteLine(number);

メソッド内のローカル変数は、そのメソッドの外から直接使用できません。

C#
public void MethodA()
{
int count = 10;
}

public void MethodB()
{
// Console.WriteLine(count); // エラー
}

複数のメソッドで共有する必要がある場合は、フィールドやプロパティとして宣言する方法があります。

7-4. 同じ名前を重複して宣言したときのエラー

同じスコープ内で同じ名前のローカル変数を重複して宣言することはできません。

C#
int count = 10;
// int count = 20; // エラー

値を変更したいだけなら、型を書かずに代入します。

C#
int count = 10;
count = 20;

別の意味を持つ値であれば、適切に名前を分けます。

C#
int itemCount = 10;
int userCount = 20;

名前を具体的にすると、重複を防げるだけでなく、コードの意味も理解しやすくなります。

7-5. 大文字・小文字の違いによるミス

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

C#
int count = 10;
int Count = 20;

countCountは別の名前です。

次のコードでは、宣言した変数名と使用する変数名の大文字・小文字が異なるため、エラーになります。

C#
string userName = "田中";
// Console.WriteLine(username); // エラー

正しくは次のとおりです。

C#
Console.WriteLine(userName);

C#の一般的な命名規則では、ローカル変数や引数にcamelCase、クラス・メソッド・プロパティにPascalCaseを使用します。

C#
public class UserAccount
{
public string UserName { get; set; } = "";

public void ShowUserName(string prefixText)
{
Console.WriteLine($"{prefixText}: {UserName}");
}
}

8. C#の宣言を正しく書くための実践例

8-1. 変数・クラス・メソッドを組み合わせたサンプルコード

次のコードでは、クラス・フィールド・プロパティ・コンストラクター・メソッド・ローカル変数を組み合わせています。

C#
using System;

namespace DeclarationSample;

public class Product
{
private readonly int id;

public string Name { get; set; }
public decimal Price { get; set; }

public Product(int id, string name, decimal price)
{
this.id = id;
Name = name;
Price = price;
}

public decimal CalculateTaxIncludedPrice(decimal taxRate)
{
decimal taxIncludedPrice = Price * (1 + taxRate);
return taxIncludedPrice;
}

public void ShowInfo()
{
decimal totalPrice = CalculateTaxIncludedPrice(0.1m);

Console.WriteLine($"商品ID: {id}");
Console.WriteLine($"商品名: {Name}");
Console.WriteLine($"税込価格: {totalPrice}円");
}
}

public class Program
{
public static void Main()
{
Product product =
new Product(1, "キーボード", 5000m);

product.ShowInfo();
}
}

このサンプルには、C#でよく使われる宣言が含まれています。

C#
public class Product

Productクラスの宣言です。

C#
private readonly int id;

読み取り専用フィールドの宣言です。

C#
public string Name { get; set; }

文字列型プロパティの宣言です。

C#
public decimal CalculateTaxIncludedPrice(decimal taxRate)

decimal型の値を返し、decimal型の引数を受け取るメソッドの宣言です。

C#
decimal totalPrice = CalculateTaxIncludedPrice(0.1m);

ローカル変数の宣言と初期化です。

C#
Product product = new Product(1, "キーボード", 5000m);

Product型の変数宣言、インスタンス生成、初期化を同時に行っています。

8-2. 宣言から処理実行までの流れ

C#のコードは、主に次のような流れで構成されます。

最初にクラスを宣言します。

C#
public class Calculator
{
}

次に、クラス内にメソッドを宣言します。

C#
public class Calculator
{
public int Add(int a, int b)
{
return a + b;
}
}

クラスのインスタンスを生成します。

C#
Calculator calculator = new Calculator();

引数を渡してメソッドを呼び出します。

C#
int result = calculator.Add(10, 20);

最後に、処理結果を利用します。

C#
Console.WriteLine(result);

全体をまとめると、次のようになります。

C#
public class Calculator
{
public int Add(int a, int b)
{
return a + b;
}
}

public class Program
{
public static void Main()
{
Calculator calculator = new Calculator();
int result = calculator.Add(10, 20);

Console.WriteLine(result);
}
}

宣言しただけでは処理は実行されません。インスタンスを生成したり、メソッドを呼び出したりすることで、実際の処理が進みます。

8-3. 初心者向けのコードの読み解き方

宣言を含むコードを読むときは、左から順にすべて理解しようとするより、構成要素を分けて確認すると分かりやすくなります。

たとえば、次のメソッドを考えます。

C#
public static int Add(int firstNumber, int secondNumber)
{
return firstNumber + secondNumber;
}

最初にメソッド名を確認します。

C#
Add

次に戻り値の型を確認します。

C#
int

このメソッドは整数を返します。

続いて引数を確認します。

C#
int firstNumber, int secondNumber

2つの整数を受け取ります。

最後に処理内容を確認します。

C#
return firstNumber + secondNumber;

2つの引数を加算して返しています。

クラス宣言を読む場合も、次の順番で確認すると理解しやすくなります。

  1. クラス名

  2. フィールド

  3. プロパティ

  4. コンストラクター

  5. メソッド

  6. 各メソッドが利用するデータ

宣言部分を先に確認すると、そのコードが「何を受け取り、何を返し、何を保持するのか」を把握しやすくなります。

8-4. 宣言を見やすく書くための命名ルール

名前から役割が分かるようにすると、宣言を読みやすくできます。

クラス名にはPascalCaseを使用します。

C#
public class OrderService
{
}

メソッド名にもPascalCaseを使用します。

C#
public void CreateOrder()
{
}

プロパティ名にもPascalCaseを使用します。

C#
public string CustomerName { get; set; } = "";

ローカル変数や引数にはcamelCaseを使用します。

C#
decimal totalPrice = 1000m;

public void SetPrice(decimal newPrice)
{
}

定数にはPascalCaseを使用する書き方が一般的です。

C#
public const int MaxRetryCount = 3;

また、短すぎる名前は避け、値の意味が分かる名前を付けましょう。

C#
int x = 10;

処理内容によっては、次のほうが分かりやすくなります。

C#
int itemCount = 10;

真偽値には、状態や判定結果だと分かる名前が適しています。

C#
bool isActive = true;
bool hasPermission = false;
bool canEdit = true;

メソッドには、処理を表す動詞を含めます。

C#
CalculateTotalPrice();
CreateUser();
SaveFile();
ValidateInput();

適切な名前を付けることは、宣言の意味を明確にし、保守しやすいコードを書くうえで重要です。

9. C#の宣言に関するよくある質問

9-1. C#の宣言と初期化は何が違う?

宣言は、変数の名前や型をプログラムに知らせることです。

C#
int count;

初期化は、変数に最初の値を設定することです。

C#
count = 0;

宣言と初期化は、同時に行うこともできます。

C#
int count = 0;

ローカル変数は、値が確実に代入されるまで読み取れません。そのため、初期値が決まっている場合は、宣言と同時に初期化する書き方が安全です。

9-2. varで宣言しても問題ない?

varで宣言しても問題ありません。コンパイラが右辺から型を決定するため、型の安全性も維持されます。

C#
var name = "田中";
var age = 20;

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

C#
// var value; // エラー
var value = 10;

また、型が分かりにくくなる場面では、明示的な型を使ったほうが読みやすい場合があります。

C#
decimal totalPrice = CalculateTotalPrice();

右辺から型が明確な場合は、varを使うと重複を減らせます。

C#
var products = new List<Product>();

varを常に使う、または常に避けるのではなく、コードの読みやすさを基準に判断しましょう。

9-3. 宣言した変数はどこから使える?

変数を使用できる範囲は、宣言した場所によって決まります。

メソッド内で宣言したローカル変数は、基本的にその変数を囲むブロックの中で使用できます。

C#
public void Sample()
{
int count = 10;
Console.WriteLine(count);
}

if文の中で宣言した変数は、通常、そのifブロック内だけで使用できます。

C#
if (true)
{
string message = "成功";
Console.WriteLine(message);
}

// messageはここでは使えない

クラスのフィールドは、アクセス修飾子やstaticの有無に応じた範囲から利用できます。

C#
public class Counter
{
private int count;

public void Increment()
{
count++;
}
}

どこから使う必要があるかを考え、必要最小限のスコープで宣言することが大切です。

9-4. クラス宣言とインスタンス生成の違いは?

クラス宣言は、データや処理の構造を決める設計図です。

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

インスタンス生成は、その設計図をもとに具体的なオブジェクトを作ることです。

C#
User user = new User();

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

C#
User user1 = new User();
User user2 = new User();

user1.Name = "田中";
user2.Name = "佐藤";

user1user2は同じUser型ですが、別々のインスタンスとして異なるデータを保持できます。

9-5. メソッド宣言で戻り値の型は必ず必要?

通常のメソッド宣言では、戻り値の型を記述する必要があります。

整数を返す場合はintを指定します。

C#
public int GetNumber()
{
return 10;
}

文字列を返す場合はstringを指定します。

C#
public string GetName()
{
return "田中";
}

値を返さない場合も、戻り値がないことを示すvoidが必要です。

C#
public void ShowMessage()
{
Console.WriteLine("こんにちは");
}

なお、クラス名と同じ名前を持つコンストラクターには戻り値の型を書きません。

C#
public class User
{
public User()
{
}
}

コンストラクターは通常のメソッドとは異なり、インスタンス生成時の初期化を行う特別なメンバーです。コンストラクターにvoidなどの戻り値の型を付けると、コンストラクターではなく通常のメソッドとして解釈されます。

まとめ

C#の宣言とは、変数・クラス・メソッドなどの名前や型、使い方をプログラムに知らせるための記述です。

変数は、型と変数名を指定して宣言します。

C#
int age;

宣言と同時に初期化することもできます。

C#
int age = 20;

クラスはclassキーワードを使って宣言します。

C#
public class User
{
}

メソッドは、アクセス修飾子・戻り値の型・メソッド名・引数を組み合わせて宣言します。

C#
public int Add(int a, int b)
{
return a + b;
}

C#では、ほかにもプロパティ、フィールド、配列、列挙型、インターフェイス、名前空間など、さまざまな要素を宣言します。

宣言を書くときは、次の点を意識することが大切です。

  • 保存する値に適した型を選ぶ

  • ローカル変数は使用前に初期化する

  • 必要以上に広いアクセス修飾子を指定しない

  • 変数のスコープを確認する

  • 大文字と小文字を正しく区別する

  • 名前から役割が分かるようにする

  • staticconstなどを目的に応じて使い分ける

最初は、変数宣言・クラス宣言・メソッド宣言の3つから理解するとよいでしょう。それぞれの宣言が何を表し、どの範囲から利用できるのかを確認しながらコードを書くことで、C#の基本構造を理解しやすくなります。