C#のinternalについて分かりやすく解説!|C#のinternalを正しく使いこなそう

- システム
エンジニア - C#でpublicやprivateは分かるのですが、同じアクセス修飾子のinternalはどのような機能を持っているのですか。
- プロジェクト
マネージャー - internalは同じアセンブリならアクセスできます。アセンブリとはexeやdllのことです。
C#のinternalとは?
C#にはinternalというキーワードがありますが、使ったことが無いので分からない人も多いのではないでしょうか。
internalとはアクセス修飾子の一つですが、何か分からない人もいるのではないでしょうか。まずはそこから説明しましょう。
アクセス修飾子は、クラスとそのメンバーのフィールド・メソッドのアクセスできる範囲を定める機能を持っています。あるクラスのメソッドをどこからでも呼べるようにしたい、もしくは隠してクラスの中でしか呼べないようにしたい、といった時に使用します。
6種類のアクセス制御子
C#のアクセス制御子には以下の6種類があります。C#をある程度使っている人なら、publicやprivateについてはご存じでしょう。
public あらゆる所からアクセスできる
private 同じクラス内のみアクセスできる
protected 同じクラスと派生したクラスのみアクセスできる
internal 同じアセンブリならアクセスできる
protected internal 同じアセンブリと別アセンブリの派生クラスでアクセスできる
private protected 同じクラスと同じアセンブリの派生したクラスのみアクセスできる
アセンブリとは何か?
C#の6つのアクセス修飾子について、publicとprivateはわかると思います。protectedも、派生した子クラスからも呼べると言えば理解できるでしょう。
しかしinternalの「同じアセンブリならアクセスできる」はピンとこないのではないでしょうか。internalを理解するには、アセンブリの意味を分かる必要があります。簡単に言うと、アセンブリとはexeやdllのことです。
同じアセンブリとは同じプロジェクトのこと
アセンブリはexeやdllのこと、とだけ言われても、まだよくわからないと思います。Visual Studioの場合で言えば、同じアセンブリ内とは同じプロジェクト内ということです。具体的にC#のサンプルで見て行きましょう。
class TestClass
{
internal string str;
}
class Program
{
public static void Main()
{
TestClass t = new TestClass();
t.str = “a”;
}
}
internalは別のクラスからアクセスできる
上のサンプルのTestClassクラスとProgramクラスは同じファイル内に記述しています。TestClassのstrフィールドはinternalが付いていて、ProgramのMainメソッドからアクセスできています。このようにinternalは同じファイルの別のクラスからアクセスすることができます。
では、次に別ファイルのクラスで試しましょう。Visual Studioのソリューションエクスプローラーでプロジェクトのプロパティを右クリックして、追加から新しい項目でTestClass.csを追加してください。
internalは別ファイルのクラスからもアクセスできる
TestClass.csのクラスにinternalのフィールドを追加してください。なおnamespaceのTestAppはプロジェクト名によって違います。
namespace TestApp
{
class TestClass
{
internal string str;
}
}
そしてMainメソッドに以下のように記述してください。internalのフィールドにアクセスできることがわかります。
public static void Main()
{
TestApp.TestClass t = new TestApp.TestClass();
t.str = “a”;
}
internalとpublicの違いはdllを作ると分かる
ここまで読んで、「これってpublicと同じじゃない?」と思った人もいるのではないでしょうか。その通りで、ここまで行ったことをinternalではなくpublicでやっても、同じようにアクセスできます。
internalとpublicの違いは、dllを作るとわかります。その前にまずexeやdllについて簡単に説明しましょう。Visual Studioで言えば、コンソールアプリのプロジェクトがexe、クラスライブラリのプロジェクトがdllになります。
コンソールアプリのプロジェクトにはMainメソッドがあり、ビルドするとWindows上で動作するexeファイルが作られます。クラスライブラリのプロジェクトで出来るのはdllファイルで、これはexeファイルから参照して使用します。dllは単体で動作しませんが、exeでよく使う共通処理を入れるために使うもので、ライブラリとも呼ばれます。
dllを作成する
それではdllを作成しましょう。まずVisual Studioで新規にC#のクラスライブラリのプロジェクトを作成してください。名前はTestDllとします。そしてTestDllのcsファイルに以下のように記述してソリューションをビルドしてください。
namespace TestDll
{
public class TestClass
{
public string p_str;
internal string i_str;
}
}
そしてVisual Studioのメニューのファイルから最近使ったプロジェクトとソリューションで、今まで使っていたMainメソッドのあるプロジェクトに戻ってください。プロジェクトを閉じて立ち上げ直すよりも、ずっと速く切り替えられます。
プロジェクトにdllを追加する
そしてソリューションエクスプローラーの「依存関係」をクリックし「COM参照を追加」を選択してください。次に参照マネージャーの右下の「参照(B)」ボタンを押してから、Test.dllを選択します。
なおTest.dllのある場所は「C:\Users\(ユーザー名)\source\repos\TestDll\TestDll\bin\Debug\netstandard2.0」ですが、環境によって少し違うかもしれません。
internalは別のアセンブリからはアクセスできない
dllが追加できれば、依存関係のアセンブリにTestDllが追加されます。
それではMainメソッドに以下を記述しましょう。
public static void Main()
{
TestDll.TestClass t = new TestDll.TestClass();
t.p_str = “a”;
t.i_str = “b”;
}
するとp_strへのアクセスは問題なくできますが、i_strはエラーになります。これはi_strがp_strと違い、publicではなくinternalだからです。internalは同じアセンブリ、つまり同じexeかdllからしかアクセスできないということが分かって頂けたのではないでしょうか。
protected internalについて
最後にprotected internalについて説明しましょう。プロジェクトをTestDllに切り替えて、C#のソースを以下のように修正してください。そしてソリューションをビルドします。
namespace TestDll
{
public class TestClass
{
public string p_str;
protected internal string i_str;
}
}
dllのクラスを派生してprotected internalにアクセスする
そしてMainメソッドのあるプロジェクトに切り替えて、C#のソースを以下のように記述してください。
class SubClass : TestDll.TestClass
{
public void SetISTR(string str)
{
i_str = str;
Console.WriteLine(i_str + “を代入しました。”);
}
}
class Program
{
public static void Main()
{
SubClass s = new SubClass();
s.SetISTR(“abc”);
}
}
protected internalはinternalより融通が利く
上のC#ソースのSubClassは、dllのTestClassを派生した子クラスということです。実行すると以下が表示されます。
abcを代入しました。
このようにprotected internalは、別のアセンブリからでも派生クラスならアクセスすることができるのです。ただし以下のように派生せずにアクセスした場合は、internalと同様にエラーになります。
TestDll.TestClass t = new TestDll.TestClass();
t.i_str = “b”;
- システム
エンジニア - internalはdllを作成するためにも知っておく必要がありそうですね。
- プロジェクト
マネージャー - その通りです。protected internalの理解のためにも必要な知識です。
internalをアクセス制御に活用しよう
C#のinternalについて解説しましたが、ご理解頂けましたでしょうか。
internalはdll内で自由に使いたいものの、外部には公開したくないフィールドやメソッドには有効に活用できますね。
FEnet.NETナビ・.NETコラムは株式会社オープンアップシステムが運営しています。
株式会社オープンアップシステムはこんな会社です
秋葉原オフィスには株式会社オープンアップシステムをはじめグループのIT企業が集結!
数多くのエンジニアが集まります。

-
スマホアプリから業務系システムまで
スマホアプリから業務系システムまで開発案件多数。システムエンジニア・プログラマーとしての多彩なキャリアパスがあります。
-
充実した研修制度
毎年、IT技術のトレンドや社員の要望に合わせて、カリキュラムを刷新し展開しています。社内講師の丁寧なサポートを受けながら、自分のペースで学ぶことができます。
-
資格取得を応援
スキルアップしたい社員を応援するために資格取得一時金制度を設けています。受験料(実費)と合わせて資格レベルに合わせた最大10万円の一時金も支給しています。
-
東証プライム上場企業グループ
オープンアップシステムは東証プライム上場「株式会社オープンアップグループ」のグループ企業です。
安定した経営基盤とグループ間のスムーズな連携でコロナ禍でも安定した雇用を実現させています。
株式会社オープンアップシステムに興味を持った方へ
株式会社オープンアップシステムでは、開発系エンジニア・プログラマを募集しています。
年収をアップしたい!スキルアップしたい!大手の上流案件にチャレンジしたい!
まずは話だけでも聞いてみたい場合もOK。お気軽にご登録ください。


C#新着案件New Job
-
システム開発/東京都新宿区/【WEB面談可/C#経験者/20代前半の方活躍中/経験1年以上の方活躍中】/在宅勤務
月給29万~34万円東京都新宿区(新宿駅) -
システム開発/東京都新宿区/【WEB面談可/C#経験者/20代後半~40代の方活躍中/経験年数不問】/在宅勤務
月給41万~50万円東京都新宿区(新宿駅) -
デバック、テスト項目の作成/神奈川県横浜市/【WEB面談可/C#経験者/20代前半の方活躍中/経験1年以上の方活躍中】/在宅勤務
月給29万~34万円神奈川県横浜市(桜木町駅) -
デバック、テスト項目の作成/神奈川県横浜市/【WEB面談可/C#経験者/20代後半~40代の方活躍中/経験年数不問】/在宅勤務
月給41万~50万円神奈川県横浜市(桜木町駅) -
基幹システム開発導入/東京都新宿区/【WEB面談可/C#経験者/20代前半の方活躍中/経験1年以上の方活躍中】/在宅勤務
月給29万~34万円東京都新宿区(西新宿駅) -
基幹システム開発導入/東京都新宿区/【WEB面談可/C#経験者/20代後半~40代の方活躍中/経験年数不問】/在宅勤務
月給41万~50万円東京都新宿区(西新宿駅)