从抽象类反映实现的私有方法?

时间:2012-06-20 08:01:40

标签: c# reflection

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

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

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值。如果我使用这里的代码,我会得到一个关于内部NullReferenceException的例外情况。


我的hack在lib中生成了NullReferenceException到目前为止我的错。上面的代码现在已经修复了(简化时有3个错误)。

2 个答案:

答案 0 :(得分: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 {
}

据我所知,反思只适用于公共成员/方法/等。反正。

答案 1 :(得分: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" });
}