C#
 Computer >> コンピューター >  >> プログラミング >> C#

C#で使えるアクセス修飾子の種類とは?6つの修飾子の違いを徹底解説

アクセス修飾子(Access Modifier)とは、クラスのメンバーやクラスそのものに対するアクセス範囲(可視性)を指定するためのキーワードです。C#には、以下の6種類のアクセス修飾子が用意されています。

  • public(パブリック)
  • private(プライベート)
  • protected(プロテクテッド)
  • internal(インターナル)
  • protected internal(プロテクテッド・インターナル)
  • private protected(プライベート・プロテクテッド)

public:すべての場所からアクセス可能

public を付けたメンバーは、プロジェクト内のどこからでも制限なくアクセスできます。外部に公開したいメソッドやプロパティなどに使用される、最も開放度の高い修飾子です。

コード例

using System;
namespace MyApplication {
    public class Program {
        public static void Main() {
            Person person = new Person();
            Console.WriteLine(person.Name);
            // Nameはpublicなので、どこからでもアクセス可能
        }
    }

    public class Person {
        public string Name = "Mark";
    }
}

private:同一クラス内からのみアクセス可能

private を付けたメンバーは、同じクラスまたは構造体の内部からしかアクセスできません。クラスの外部からは参照できないため、フィールドの隠蔽(カプセル化)に活用されます。

コード例

using System;
namespace MyApplication {
    public class Program {
        public static void Main() {
            Person person = new Person();
            Console.WriteLine(person.Name);
            // Nameはprivateのため、Personクラスの外部からはアクセスできない
            // コンパイルエラー: 'Person.Name' is inaccessible due to its protection level
        }
    }

    public class Person {
        private string Name = "Mark";
    }
}

protected:継承した派生クラスからもアクセス可能

protected を付けたメンバーは、定義されたクラスの内部と、そのクラスを継承したすべての派生クラスからアクセスできます。ただし、継承関係のない外部クラスからはアクセスできません。

コード例

using System;
namespace MyApplication {
    public class Program {
        public static void Main() {
            Employee employee = new Employee();
            employee.Print(); // 出力: Mark

            Person person = new Person();
            Console.WriteLine(person.Name);
            // コンパイルエラー: 'Person.Name' is inaccessible due to its protection level
        }
    }

    public class Person {
        protected string Name = "Mark";
    }

    public class Employee : Person {
        public void Print() {
            Console.WriteLine(Name); // 派生クラスからはアクセス可能
        }
    }
}

internal:同一アセンブリ(プロジェクト)内からのみアクセス可能

internal を付けたメンバーは、現在のプロジェクト(アセンブリ)内で定義されたコードからのみアクセスできます。アセンブリの外部には公開されないため、ライブラリ内部でのみ使いたい機能に適しています。

コード例(Project 1:同一アセンブリ内)

using System;
namespace MyApplication {
    public class Program {
        public static void Main() {
            Person person = new Person();
            Console.WriteLine(person.Name); // 出力: Mark
        }
    }

    public class Person {
        internal string Name = "Mark";
    }
}

実行結果

Mark

コード例(Project 2:別アセンブリからアクセス)

using MyApplication;
using System;

namespace Project2 {
    public class Project2Class {
        public void Print() {
            Person person = new Person();
            Console.WriteLine(person.Name);
            // コンパイルエラー: 'Person.Name' is inaccessible due to its protection level
        }
    }
}

protected internal:同一アセンブリ内+別アセンブリの派生クラスからアクセス可能

protected internal は、protectedinternal を組み合わせた修飾子です。同じアセンブリ内のすべてのコードに加えて、別アセンブリに存在する派生クラスからもアクセスできます。

コード例(Project 1:同一アセンブリ内)

using System;
namespace MyApplication {
    public class Program {
        public static void Main() {
            Person person = new Person();
            Console.WriteLine(person.Name); // 出力: Mark
        }
    }

    public class Person {
        protected internal string Name = "Mark";
    }
}

実行結果

Mark

コード例(Project 2:別アセンブリの派生クラスからアクセス)

using MyApplication;
using System;

namespace Project2 {
    public class Project2Class : Person {
        public void Print() {
            Console.WriteLine(Name); // 出力: Mark(別アセンブリでも派生クラスならアクセス可能)
        }
    }
}

private protected:同一アセンブリ内の派生クラスからのみアクセス可能

private protected は、privateprotected を組み合わせた修飾子です。包含クラスの内部、またはそれを継承したクラスからアクセスできますが、同一アセンブリ(プロジェクト)内に限られます。別のアセンブリからアクセスしようとするとコンパイルエラーになります。この修飾子は C# 7.2 以降で利用可能です。

コード例

using System;
namespace MyApplication {
    public class Person {
        private protected string Name = "Mark";
    }

    public class Employee : Person {
        public void Print() {
            Console.WriteLine(Name); // OK: 同一アセンブリ内の派生クラスからアクセス可能
        }
    }

    public class Program {
        public static void Main() {
            Employee employee = new Employee();
            employee.Print(); // 出力: Mark

            Person person = new Person();
            // Console.WriteLine(person.Name);
            // コンパイルエラー: 同一アセンブリでも非派生クラスからはアクセス不可
        }
    }
}

アクセス修飾子の比較一覧表

6つのアクセス修飾子のアクセス範囲をまとめると、次のようになります。

アクセス修飾子同一クラス内同一アセンブリの派生クラス同一アセンブリの非派生クラス別アセンブリの派生クラス別アセンブリの非派生クラス
public
protected internal×
internal××
protected××
private protected×××
private××××

用途に応じて適切なアクセス修飾子を選択することで、カプセル化の精度が高まり、安全性と保守性に優れたコードを書くことができます。

  1. C# ASP.NET Web APIのフィルターの種類と使い方を徹底解説

    ASP.NET Web APIフレームワークでは、リクエスト処理のさまざまな段階に追加のロジックを組み込むために「フィルター」が使用されます。フィルターは、ロギング、認可、キャッシュといった横断的関心事(クロスカッティングコンサーン)を実装するための仕組みであり、アクションメソッドやコントローラーに対して、宣言的またはプログラム的に適用できます。ここでは、C#のWeb APIで利用できる主なフィルターの種類について詳しく見ていきましょう。Web APIの主なフィルターの種類1. 認証フィルター(Authentication Filter)認証フィルターは、ユーザーの身元情報を検証するために使用

  2. Pythonで使える引用符の種類と使い方をわかりやすく解説

    Pythonにおける引用符の基本Pythonでは、文字列(string)オブジェクトを作成する際に引用符を使用します。Pythonが認識できる引用符は、シングルクォート()、ダブルクォート()、そしてトリプルクォート( または )の3種類です。文字列リテラルは、一連の文字をシングルクォート(hello)、ダブルクォート(hello)、またはトリプルクォート(hello や hello)で囲むことで記述できます。どの引用符を使っても、生成される文字列オブジェクトはまったく同じものになります。>>> var1=hello >>> var1 hello >&