2

i totaly got stuck in a Reflection Problem, i think it isn't real big, but i don't find any solution for this.

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...
    }
}

The Interface looks this way:

public interface myClassIF {

    void DecideAndCall(string identifier);

}

If i call the GetMethod("...")-Method, i always got a NullReference. I can't understand this, because in an other Part of this Project i've done this before. But there i used Refelction to an other Type not to "this".

Is it possible to Reflect Methods in the actually instanciated Object? I think i'd should be, but i don't know how...

Many Thanks! Benni

Gimly
  • 5,975
  • 3
  • 40
  • 75
Benni
  • 141
  • 2
  • 5
  • How are you calling `DecideAndCall`? Are you definitely passing an "A" or a "B"? GetMethod will throw an ArgumentNullException if the method is not found, could that be what you are seeing? Alternatively, break the statement down into several steps to find out which part is throwing the Null reference. – Lazarus Jan 28 '11 at 12:37
  • I do not get a null reference exception when I run your code like this: `var instance = new myClass(); instance.DecideAndCall("A");` and even when I replace `"A"` with e.g. `"C"` or `null`. Could you please create a new project which reproduces the exception? – Pieter van Ginkel Jan 28 '11 at 12:37
  • 1
    Although this doesn't answer the question wouldn't it be better to just switch based on the supplied identifier in each class. Using reflection to do something like that will be very slow in comparison to simple switch although I realise it may not be as quick to code. – Hawxby Jan 28 '11 at 12:38

4 Answers4

12

The method you want to retrieve is private, but the parameterless Type.GetMethod method only looks for public methods. Try the overload that lets you specify binding-constraints:

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

I would strongly recommend against doing something like this though. It's highly unusual for an object to perform reflection on itself. You obviously lose type-safety; for example, your provided sample will fail spectacularly if the argument to the method is something other than "A" or "B". Although I'm sure your real program is more complicated, are you sure you can't redesign this in a way that doesn't require reflection?

Ani
  • 111,048
  • 26
  • 262
  • 307
2

The methods you're interested in are private, so you'll need to specify BindingFlags.NonPublic in your arguments:

public void DecideAndCall(string identifier)
{
    string methodName = "doSomething_" + identifier;

    BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic;
    MethodInfo mi = this.GetType().GetMethod(methodName, flags);
    // ...
}
LukeH
  • 263,068
  • 57
  • 365
  • 409
2

YOu need to use the BindingFlags.NonPublic to get to private methods.

gbvb
  • 866
  • 5
  • 10
1

Since the methods are private, you need to use the overload taking BindingFlags

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

This is discussed in more detail here

Community
  • 1
  • 1
StuartLC
  • 104,537
  • 17
  • 209
  • 285