【问题标题】:C# Reflection on this-Object对此对象的 C# 反射
【发布时间】:2011-01-28 20:42:25
【问题描述】:

我完全陷入了反射问题,我认为这不是什么大问题,但我没有找到任何解决方案。

public class myClass : myClassIF {

    public myClass() { }

    private void doSomething_A() {
        //...
    }

    private void doSomething_B() {
        //...
    }

    public void DecideAndCall(string identifier) {
        string methodName = "doSomething_" + identifier;
        MethodInfo mi = this.GetType().GetMethod(methodName); //here i got a NullReference??
        //here should be the Invocation of the Method and so on...
    }
}

界面是这样的:

public interface myClassIF {

    void DecideAndCall(string identifier);

}

如果我调用 GetMethod("...")-Method,我总是得到一个 NullReference。我无法理解这一点,因为在该项目的其他部分中,我之前已经这样做过。但是我在那里使用了对另一种类型的反射,而不是“这个”。

是否可以在实际实例化的对象中反映方法?我想我应该是,但我不知道如何......

非常感谢! 本尼

【问题讨论】:

  • 你怎么打电话给DecideAndCall?你确定是通过“A”还是“B”?如果找不到该方法,GetMethod 将抛出 ArgumentNullException,这可能是您所看到的吗?或者,将语句分解为几个步骤,以找出抛出 Null 引用的部分。
  • 当我像这样运行您的代码时,我没有得到空引用异常:var instance = new myClass(); instance.DecideAndCall("A");,即使我用例如替换"A" "C"null。您能否创建一个重现异常的新项目?
  • 虽然这不能回答这个问题,但根据每个类中提供的标识符进行切换不是更好。与简单的 switch 相比,使用反射来做类似的事情会非常慢,尽管我意识到它可能没有那么快编码。

标签: c# reflection


【解决方案1】:

您要检索的方法是私有的,但无参数的Type.GetMethod 方法只查找公共方法。试试overload,它可以让你指定绑定约束:

BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic;
MethodInfo mi = GetType().GetMethod(methodName, flags);

我强烈建议不要做这样的事情。对象对自身执行反射是极不寻常的。你显然失去了类型安全;例如,如果方法的参数不是"A""B",您提供的示例将失败。虽然我确定您的实际程序更复杂,但您确定不能以不需要反射的方式重新设计它吗?

【讨论】:

    【解决方案2】:

    您感兴趣的方法是私有的,因此您需要在参数中指定BindingFlags.NonPublic

    public void DecideAndCall(string identifier)
    {
        string methodName = "doSomething_" + identifier;
    
        BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic;
        MethodInfo mi = this.GetType().GetMethod(methodName, flags);
        // ...
    }
    

    【讨论】:

      【解决方案3】:

      您需要使用BindingFlags.NonPublic 来访问私有方法。

      【讨论】:

        【解决方案4】:

        由于方法是私有的,所以需要使用带BindingFlags的重载

        MethodInfo mi = typeof(myClass).GetMethod(methodName, BindingFlags.Instance | BindingFlags.NonPublic); 
        

        这会更详细地讨论here

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2010-11-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多