C# アクセス修飾子を理解する:public、private、protected、internal など
C# アクセス修飾子を理解する
このガイドでは、C# のさまざまなアクセス修飾子—public、private、protected、internal、protected internal、private protected—が型とメンバーの可視性をどう制御するかを、実践的なコード例で解説します。
C# では、アクセス修飾子によってフィールドの読み書き、メソッドの呼び出し、型のインスタンス化が誰に許可されるかを決定します。例:
class Student {
public string name;
private int num;
}
ここでは name はどこからでもアクセス可能ですが、num は Student クラス内に限定されます。
アクセス修飾子の種類
- public
- private
- protected
- internal
- protected internal
- private protected
1. public アクセス修飾子
型やメンバーを public でマークすると、そのアセンブリを参照できるすべてのコードからアクセス可能になります。
using System;
namespace MyApplication {
class Student {
public string name = "Sheeran";
public void Print() {
Console.WriteLine("Hello from Student class");
}
}
class Program {
static void Main(string[] args) {
Student student1 = new Student();
Console.WriteLine("Name: " + student1.name);
student1.Print();
Console.ReadLine();
}
}
}
出力
Name: Sheeran Hello from Student class
フィールドとメソッドの両方が public なので、Program クラスから自由にアクセスできます。
ヒント: オブジェクト student1 を使って Student のメンバーにアクセスしています。詳細は C# クラスとオブジェクト を参照してください。
2. private アクセス修飾子
private メンバーは、宣言した class または struct 内でのみ可視です。外部コードからはコンパイル時エラーになります。
using System;
namespace MyApplication {
class Student {
private string name = "Sheeran";
private void Print() {
Console.WriteLine("Hello from Student class");
}
}
class Program {
static void Main(string[] args) {
Student student1 = new Student();
Console.WriteLine("Name: " + student1.name);
student1.Print();
Console.ReadLine();
}
}
}
name や Print を Program からアクセスしようとすると:
CS0122 'Student.name' is inaccessible due to its protection level
CS0122 'Student.Print()' is inaccessible due to its protection level
3. protected アクセス修飾子
protected でマークされたメンバーは、自身のクラスと派生クラスからアクセス可能です。アセンブリをまたがっても有効です。
using System;
namespace MyApplication {
class Student {
protected string name = "Sheeran";
}
class Program : Student {
static void Main(string[] args) {
Program program = new Program();
Console.WriteLine("Name: " + program.name);
Console.ReadLine();
}
}
}
出力
Name: Sheeran
ここでは Program が Student を継承しているため、protected な name フィールドにアクセスできます。
4. internal アクセス修飾子
internal メンバーは、同じアセンブリ(コンパイル済みコードの論理単位)内でのみ可視です。プロジェクトをビルドするとコンパイラがアセンブリを作成します。
単一アセンブリ内では:
using System;
namespace Assembly {
class Student {
internal string name = "Sheeran";
}
class Program {
static void Main(string[] args) {
Student theStudent = new Student();
Console.WriteLine("Name: " + theStudent.name);
Console.ReadLine();
}
}
}
出力
Name: Sheeran
同じアセンブリ内でアクセスしようとすると、internal メンバーはアセンブリ全体で共有されるため public と同様に振る舞います。
別のアセンブリではアクセス不可:
// Assembly1
using System;
namespace Assembly1 {
public class StudentName {
internal string name = "Sheeran";
}
}
// Assembly2
using System;
using Assembly1;
namespace Assembly2 {
class Program {
static void Main(string[] args) {
StudentName student = new StudentName();
Console.Write(student.name); // CS0122
Console.ReadLine();
}
}
}
Assembly2 のコンパイルを試みると:
CS0122 'StudentName.name' is inaccessible due to its protection level
5. protected internal アクセス修飾子
protected internal の組み合わせにより、同じアセンブリ内から、または他のアセンブリの派生型からアクセス可能になります。
// Assembly1
using System;
namespace Assembly1 {
public class Greet {
protected internal string msg = "Hello";
}
}
// Assembly2
using System;
using Assembly1;
namespace Assembly2 {
class Program : Greet {
static void Main(string[] args) {
Program greet = new Program();
Console.Write(greet.msg);
Console.ReadLine();
}
}
}
出力
Hello
6. private protected アクセス修飾子
C# 7.2 で導入された private protected は、宣言クラスと同じアセンブリ内の派生クラスのみに可視性を制限します。
// Assembly1
using System;
namespace Assembly1 {
public class StudentName {
private protected string name = "Sheeran";
}
class Program1 : StudentName {
static void Main(string[] args) {
Program1 student = new Program1();
Console.Write(student.name);
Console.ReadLine();
}
}
}
// Assembly2
using System;
using Assembly1;
namespace Assembly2 {
class Program : StudentName {
static void Main(string[] args) {
Program student = new Program();
Console.Write(student.name); // CS0122
Console.ReadLine();
}
}
}
Assembly2 からのアクセスは、メンバーがそのアセンブリを超えて公開されないため、派生型であっても失敗します。
注意: 型(クラス、インターフェース等)は public と internal のみ使用可能ですが、他の修飾子はメンバーにのみ適用されます。
C言語
- C# クラスとオブジェクト:堅牢な OOP の基礎
- C# static キーワード:静的変数、メソッド、クラスをマスターする
- C# 抽象クラスと抽象メソッドをマスターする:実践ガイド
- C# 入れ子クラスを理解する:定義、使用法、継承
- C# 部分クラスと部分メソッドを理解する
- C# sealed クラスとメソッドをマスターする:使用判断、実例、コードの安全性とパフォーマンス向上
- C++クラステンプレート完全ガイド:実践的なジェネリックプログラミング
- C言語ストレージクラス完全理解:スコープ・ライフタイム・パフォーマンス
- C++ポリモーフィズム完全理解:仮想関数と純粋仮想関数
- C++データ抽象化完全マスター:インターフェースと実装の分離
- Java修飾子完全ガイド:アクセス/非アクセス修飾子の種類と使い分け