アクセス修飾子
アクセス修飾子とは、型やそのメンバの公開範囲を指定するもの4種とその組み合わせをもつ2種の計6種
public | 公開 | どこからでもアクセス可能 |
protected | 保護 | 同じクラス内(構造体内)とその派生クラスからのみアクセス可能 |
internal | 内部 | 定義されているアセンブリ内からのみアクセス可能 |
private | 非公開 | 同じクラス(構造体)内からのみアクセス可能 |
protected internal | 保護・内部 | 同一アセンブリ内と他アセンブリでも派生クラスならアクセス可能 |
private protected | 保護・内部 | 同一アセンブリ内の同じクラスと派生クラスならアクセス可能 |
C# 7.2からprivate protectedが追加されました
インナークラス
インナークラス(内部クラス)から親クラス(外部クラス)のメンバにはアクセス指定に関わらずなんでもアクセス可能
class Parent
{
// privateを指定
private int _count;
private Inner _inner;
public Parent()
{
_inner = new Inner(this);
}
public class Inner
{
Parent _parent;
public Inner(Parent parent)
{
_parent = parent;
}
public int GetCount()
{
// 内部クラスからは外部クラスのprivateにアクセスできる
return _parent._count;
}
}
}
フレンドアセンブリ
内部公開(internal)に指定されたクラスは、そのアセンブリ内からのみアクセスが可能であるが、フレンドアセンブリとして明示的な指定がある場合は、そのアセンブリからもアクセス可能となるInternalに定義されたクラスなどに対する単体テストコードからのアクセスを想定した機能であろうが、今時のテストフレームでInternalやPrivateにアクセスできないなんてこともないので、ほとんど見かけない。
using System.Runtime.CompilerServices;
// この指定によりTestsuiteSample.dll内に定義されたクラスからはアクセス可能となる
[assembly:InternalsVisibleTo("TestsuiteSample")]
namespace ClassLibrary
{
// internal指定なので他アセンブリからアクセスは不可
internal static class Sample
{
internal static int MaxCount
{
get { return 100; }
}
}
}
リフレクション
リフレクションを使えばどのようなアクセス指定のクラスやメンバでもアクセス可能
public static class Sample
{
private static int _count = 100;
public static int Count
{
get { return _count; }
}
}
using System.Reflection;
class Program
{
static void Tester()
{
// _countという静的で非公開なフィールドを取得し
var field = typeof(ClassLibrary.Sample2).GetField("_count", BindingFlags.Static | BindingFlags.NonPublic);
// それに値を設定する(第一引数はインスタンスクラスの場合に設定対象のインスタンスを指定する)
field.SetValue(null, 200);
}
}