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
を公開できる。
エラーが発生した場合は、クラスやメソッドのアクセス修飾子を見直し、適切な可視性を設定しましょう!
ディスカッション
コメント一覧
まだ、コメントがありません