C# における internal と public の違いとエラーの原因
C# では、クラスやメソッドのアクセス範囲を制御するために アクセス修飾子 を使用します。特に internal と public を適切に使わないと、アクセス権に関するエラーが発生することがあります。
1. internal と public の違い
| アクセス修飾子 | 説明 |
|---|---|
public | どこからでもアクセス可能(他のアセンブリからも可能) |
internal | 同じアセンブリ内からのみアクセス可能(外部アセンブリからは不可) |
アセンブリ(Assembly)とは、C# のプロジェクトをビルドしたときに生成される .exe や .dll のことを指します。
2. アセンブリと Windows フォームアプリの関係
Windowsフォームアプリ(WinFormsアプリ)では、通常プロジェクトごとに1つのアセンブリとして考えます。
例えば、以下のようなソリューションを考えます。
MySolution (ソリューション)
│── MyWinFormsApp (Windowsフォームアプリ) → `MyWinFormsApp.exe`
│── MyLibrary (クラスライブラリ) → `MyLibrary.dll`
MyWinFormsApp.exeは メインの実行ファイル で、ここにinternalなクラスを作ると アプリ内でのみ利用可能 になります。MyLibrary.dllは 外部ライブラリ で、他のプロジェクトと共有できますが、internalのクラスは MyLibrary.dll の中だけで有効 になります。MyWinFormsAppからMyLibrary.dllのinternalメンバーにアクセスするにはInternalsVisibleToを設定する必要があります。
3. internal クラスの public メンバーにアクセスできない例
以下のように internal クラスの public メソッドを別のアセンブリから使おうとすると、エラーになります。
// AssemblyA にあるクラス
internal class InternalClass
{
public void PublicMethod() { }
}
// AssemblyB からアクセスを試みる
class AnotherClass
{
void Test()
{
InternalClass obj = new InternalClass(); // エラー!
obj.PublicMethod(); // ここもエラー!
}
}
この場合、PublicMethod() は public ですが、そのクラス InternalClass が internal のため、外部のアセンブリ(AssemblyB)からは そもそもクラスが見えない ためエラーになります。
4. public クラスの internal メソッドにアクセスできない例
逆に、public クラスの中に internal メソッドを作ると、クラス自体は見えるのにメソッドが使えないという状況が発生します。
// AssemblyA にあるクラス
public class PublicClass
{
internal void InternalMethod() { }
}
// AssemblyB からアクセスを試みる
class AnotherClass
{
void Test()
{
PublicClass obj = new PublicClass(); // クラスは見える
obj.InternalMethod(); // エラー!
}
}
この場合、PublicClass は public なので AnotherClass からインスタンスを作成できますが、InternalMethod() は internal なので、外部アセンブリ(AssemblyB)からはアクセスできません。
5. 解決策
(1) internal を public に変更する
外部アセンブリからアクセスさせたい場合、internal を public に変更することで解決できます。
public class InternalClass
{
public void PublicMethod() { }
}
ただし、無闇に public にすると セキュリティやカプセル化の観点で問題 になる場合があります。
(2) InternalsVisibleTo を使用する
特定のアセンブリだけに internal メンバーを公開したい場合、InternalsVisibleTo 属性を使用できます。
設定方法:
- AssemblyA の
AssemblyInfo.csに以下を追加
[assembly: InternalsVisibleTo("AssemblyB")]
- これにより、
AssemblyBからAssemblyAのinternalクラスやメソッドにアクセス可能になります。
6. まとめ
internalは 同じアセンブリ内でのみ アクセス可能。publicは どのアセンブリからも アクセス可能。internalクラスのpublicメソッドは、クラス自体が外部から見えないので使えない。publicクラスのinternalメソッドは、クラスは見えるがメソッドにアクセスできない。- Windowsフォームアプリでは、プロジェクトごとに1つのアセンブリと考える。
InternalsVisibleToを使うと、特定のアセンブリ間でinternalを公開できる。
エラーが発生した場合は、クラスやメソッドのアクセス修飾子を見直し、適切な可視性を設定しましょう!





ディスカッション
コメント一覧
まだ、コメントがありません