2

如何将私有方法称为一个类的基础?

这是我的结构的基本示例(该代码包含在参考中):

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;我会得到callme一个null价值。如果我使用像这里这样的代码,我会得到一个关于 internal 的异常大喊大叫NullReferenceException


NullReferenceException到目前为止,我的hack 我在 lib 内部生成了一个我的错。上面的代码现在已经修复(简化时有 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" });

此外,您不需要所有代码来确定是否objImplBase

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 回答