2

1 つのクラスのベースであるプライベート メソッドを呼び出すにはどうすればよいですか?

これが私の構造の基本的な例です(そのコードは参照に含まれています):

public abstract class Something {
}
internal class ImplBase : Something {
    private void CallMe(string s) {}
}
internal class RealImpl : ImplBase {
}

これまでのところ、RealImplとして表示されるインスタンスがありますSomething。メソッドにアクセスするにはどうすればよいCallMeですか?

ここでこのコードを試しています:

Type type = obj.GetType(); // returns RealImpl
bool supported = false;
// a loop to be a little more flexible
for(Type t = type; t.Name != "Object"; t = t.BaseType) {
    if(t.Name == "ImplBase") {
        supported = true;
        type = t;
        break;
    }
}
if(supported) {
    var callme = type.GetMethod("CallMe", BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(string) }, new ParameterModifier[] {});
    callme.Invoke(obj, new object[] { "hi" });
} else {
    throw new NotSupportedException("The type " + type.Name + " is not supported.");
}

コメントアウトすると、値type = t;が得られます。ここのようなコードを使用すると、 internal について叫んでいる Exception が発生します。callmenullNullReferenceException


私のハックで、NullReferenceExceptionこれまでのところ私のせいでライブラリ内に作成しました。上記のコードは現在修正されています (簡略化中に 3 つの間違いがありました)。

4

2 に答える 2

2

基本クラスのメソッドを呼び出すためにサブクラスが必要な場合は、それらのメソッドをとして宣言するかprotected、プライベートメソッドのプロキシとして機能する基本クラスの他のメソッドが必要です。

public abstract class Something {
}
internal class ImplBase : Something {
    protected void callMe(string s) {}
}
internal class RealImpl : ImplBase {
}

また

public abstract class Something {
}
internal class ImplBase : Something {
    private void callMe(string s) {}
    public void CallMe(string s) { this.callMe(s);}
}
internal class RealImpl : ImplBase {
}

私の知る限り、リフレクションはパブリックメンバー/メソッドなどでのみ機能します。とりあえず。

于 2012-06-20T08:05:58.440 に答える
2

メソッドの名前callMeはではなくCallMe、なので、次のように変更します。

var callme = type.GetMethod("callMe"...

また、それを呼び出しますobj(何であるかわからないself):

callme.Invoke(obj, new object[] { "hi" });

objさらに、そうであるかどうかを判断するために、そのすべてのコードは必要ありImplBaseません。

if(obj is ImplBase) 
{
    var callme = type.GetMethod("callMe", BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(string) }, new ParameterModifier[] {});
    callme.Invoke(obj, new object[] { "hi" });
}
于 2012-06-20T08:18:37.840 に答える