◆ 通常の方法でアクセスできないところは dynamic でもムリ

dynamic って動的になってリフレクションみたいにどこでもアクセスできるものかと思ってました

public class Outer
{
    private class Inner
    {
        public int method() => 2;
    }
}

var type = Type.GetType("sample_project.Outer+Inner, sample-project");
dynamic obj = Activator.CreateInstance(type);
Console.WriteLine(obj.method());

インナークラスのインスタンスをリフレクションで作ってプロパティやメソッドの操作はリフレクションだとめんどうだから dynamic でやろうとしたら

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'object' に 'method' の定義がありません


エラーになりました
method メソッド自体は public ですが Inner クラスは private で見れないので method メソッドの定義が見つからないのだと思います

dynamic それほど便利じゃなかった……



public なクラスを作って Inner クラスはそれを継承するようにすれば
public class Base
{
    public virtual int method() => 1;
}

public class Outer
{
    private class Inner : Base
    {
        public override int method() => 2;
    }
}
2

親クラスの 1 じゃなくて 2 が出力されました


override じゃなくて new にすれば
public class Base
{
    public virtual int method() => 1;
}

public class Outer
{
    private class Inner : Base
    {
        public new int method() => 2;
    }
}
1

1 になりました
ということは公開されてる Base のほうをみてるのかな


せっかくなのでメソッドを protected にもしてみました
public class Base
{
    protected virtual int method() => 1;
}

public class Outer
{
    private class Inner : Base
    {
        protected override int method() => 2;
    }
}

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'sample_project.Base.method()' はアクセスできない保護レベルになっています



まあそうなりますよね
アクセスしようとしてるのは Inner.method じゃなくてやっぱり Base.method のほうのようです


ということで dynamic は型を動的に扱えるだけでアクセスレベルを無視してみれるわけではありませんので注意してください