Code Fix

中級

is inaccessible due to its protection level の原因と直し方

privateなメンバーにクラスの外部からアクセスしようとすると出るコンパイルエラーです。

エラーメッセージの読み方

Program.cs(8,36): error CS0122: 'Box.secret' is inaccessible due to its protection level
Program.cs
ファイル名
8
行番号
36
列番号 — この位置でコンパイラが解析に失敗しました
CS0122
エラーコード — 検索するとMicrosoftの解説ページが見つかります
'Box.secret' is inaccessible due to its protection level
内容 — 期待していたもの、または受け付けられなかったもの

このエラーが出る典型パターン

パターン1

 1  class Box {
 2      private int secret = 42;
 3      public int visible = 100;
 4  }
 5  class Program {
 6      static void Main(string[] args) {
 7          Box b = new Box();
 8          System.Console.WriteLine(b.secret );
                                          ^
 9      }
10  }
Program.cs(8,36): error CS0122: 'Box.secret' is inaccessible due to its protection level

privateなメンバーはそのクラスの内部からしかアクセスできません。外部から使いたいならpublicにするかプロパティ経由にします。

直し方: secret を visible にします。

この問題を解いてみる →

広告
広告スロット(未設定)

パターン2

 1  class Account {
 2      private int balance = 500;
 3      public string owner = "Alice";
 4  }
 5  class Program {
 6      static void Main(string[] args) {
 7          Account a = new Account();
 8          System.Console.WriteLine(a.balance);
                                          ^
 9      }
10  }
Program.cs(8,36): error CS0122: 'Account.balance' is inaccessible due to its protection level

残高のような内部状態は隠蔽し、公開が必要な情報だけpublicにするのが一般的な設計です。

直し方: balance を owner にします。

この問題を解いてみる →

パターン3

 1  class Config {
 2      private string key = "secret-key";
 3      public string name = "app";
 4  }
 5  class Program {
 6      static void Main(string[] args) {
 7          Config c = new Config();
 8          System.Console.WriteLine(c.key );
                                         ^
 9      }
10  }
Program.cs(8,36): error CS0122: 'Config.key' is inaccessible due to its protection level

設定値の中でも機密性の高いものはprivateにして、外部から直接読めないようにします。

直し方: key を name にします。

この問題を解いてみる →

パターン4

 1  class Vault {
 2      private int code = 1234;
 3      public string label = "safe";
 4  }
 5  class Program {
 6      static void Main(string[] args) {
 7          Vault v = new Vault();
 8          System.Console.WriteLine(v.code );
                                         ^
 9      }
10  }
Program.cs(8,36): error CS0122: 'Vault.code' is inaccessible due to its protection level

privateなメンバーはそのクラスの内部からしかアクセスできません。

直し方: code を label にします。

この問題を解いてみる →

パターン5

 1  class User {
 2      private string password = "hunter2";
 3      public string username = "al";
 4  }
 5  class Program {
 6      static void Main(string[] args) {
 7          User u = new User();
 8          System.Console.WriteLine(u.password);
                                           ^
 9      }
10  }
Program.cs(8,36): error CS0122: 'User.password' is inaccessible due to its protection level

機密性の高いフィールドはprivateにして外部から直接読めないようにします。

直し方: password を username にします。

この問題を解いてみる →

よくある誤解

privateはそのクラスの内部でしか使えません。外部に公開する必要があるものだけをpublicにするのがカプセル化の基本です。

実務での勘所

C#のアクセス修飾子はprivateとpublicの二択ではありません。internalは同じアセンブリ(プロジェクトのビルド単位)の中でだけ公開したいメンバーに使い、ライブラリの外部には見せたくないが同じプロジェクト内の他のクラスからは使いたい、という場面に向いています。さらにprotected internalのように組み合わせることもできます。Javaのパッケージ非公開に近い発想ですが、C#の場合は「アセンブリ」という、フォルダ構造とは独立したビルド単位が境界になる点が異なります。

演習をはじめる

関連するエラー

広告
広告スロット(未設定)