1. C#の主なアクセス修飾子
プログラムを書くとき、「誰が」「どこから」自分の変数やメソッドを見たり変更できるか、ちゃんとコントロールしたくなるよね。これはマンションみたいなもので、全部の部屋がみんなに開いてるわけじゃない。住人だけが入れる場所もあれば、メンテナンスの人しか入れない場所もある。
プログラミングではこの「アクセスコントロール」を アクセス修飾子 でやるんだ。クラスのメンバー(変数、フィールド、メソッド、プロパティなど)がクラスの外や他のクラス、他のプロジェクトから見えるかどうかを決める。これがOOPの カプセル化 のメインの実装の一つだよ。実装の詳細を隠して、必要な「インターフェース」だけ外に出すって感じ。
主な修飾子とそのざっくり説明の表がこれ:
| 修飾子 | どこで見える?(ざっくり) |
|---|---|
|
どこでも(プロジェクト内も外も、アセンブリ参照があればOK) |
|
同じクラスの中だけ |
|
private と同じ |
難しそうに見える?実は全然難しくないよ。どこで何を使うといいか、例で見てみよう。
2. public 修飾子 — 誰でもどうぞ
public 修飾子をつけると、その変数やメソッドは どこからでも 見えるようになる。クラスのメンバーを public にしたら、そのクラスが見える他のコードからアクセスできるよ。
public class Person
{
public string Name;
public void SayHello()
{
Console.WriteLine($"やあ!僕の名前は{Name}だよ");
}
}
これでどこでも(同じプロジェクトでも他のプロジェクトでも、アセンブリ参照があれば)こう書ける:
Person p = new Person();
p.Name = "アリサ";
p.SayHello();
実践アドバイス: なんでもかんでも public にしない方がいいよ。これはコードの安全性のカギだからね。
3. private 修飾子 — これはプライベートだよ!
private 修飾子はクラスの中身へのアクセスを閉じる。外からは何があるかも見えないし、データも変えられない。C#では、修飾子を指定しないとフィールドやメソッドはデフォルトでprivate になるよ。
public class Cup
{
private double volume; // このフィールドはCupクラスだけが見える
public void Fill(double value)
{
volume = value; // クラス内なら使える
}
public double GetVolume()
{
return volume; // でも外からはvolumeがあることすら分からない
}
}
ここで volume は他からは見えないけど、Cup の中のどのメソッドからでも使える。容量を知りたいときは、publicメソッド GetVolume() を用意してるよ。
4. スコープ:変数、メソッド、クラス
スコープ っていうのは、プログラムの中で名前(変数、メソッド、クラス)が意味を持ってアクセスできる範囲のこと。
- ローカル変数(メソッドやコードブロック内で宣言):そのメソッドやブロックの中だけで見える。
- メソッドのパラメータ:そのメソッドの中だけで見える。
- クラスのフィールド:クラス内ならどこでも見える(アクセス修飾子による)。
- クラス:ネストしたクラスは private ならラップしてるクラスの中だけで見える、など。
スコープの例を見てみよう:
public class Counter
{
private int count = 0; // クラス内ならどこでも見える
public void Increment()
{
count++; // フィールドを使える
int temp = count * 2; // tempはIncrementの中だけで見える
}
public int GetCount()
{
// ここではtempは見えない!
return count;
}
}
もし temp に GetCount() の中でアクセスしようとしたら、エラーになるよ。
5. 変数のシャドウイング(shadowing)
シャドウイング っていうのは、あるスコープで同じ名前の変数(やパラメータ)を宣言したときに起きる現象。内側のブロックで「新しい」名前が「古い」名前を 隠す から、外側の値には直接アクセスできなくなる。
シャドウイングの例:
class ShadowDemo
{
int value = 10; // クラスのフィールド
void PrintValue()
{
Console.WriteLine(value); // 10 — クラスのフィールド
int value = 5; // ローカル変数がフィールドを隠す
Console.WriteLine(value); // 5が出る、10じゃなくて
}
}
この例だと、int value = 5; って書いた時点で、メソッド内ではクラスのフィールドが 隠される。PrintValue() の中で value にアクセスするとローカル変数の方が使われる。
どうしてもクラスのフィールドにアクセスしたいときは、this キーワードを使う:
class ShadowDemo
{
int value = 10;
void PrintValue()
{
Console.WriteLine(value); // 10 — フィールド
int value = 5;
Console.WriteLine(value); // 5 — ローカル変数
Console.WriteLine(this.value); // 10 — フィールド
}
}
シャドウイングはややこしくなるから、特に大きなチームでやるときは変数に分かりやすくて違う名前をつけるのがおすすめだよ。
GO TO FULL VERSION