Late binding: call a method by string name

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

Is there a way to execute a method if all we know is its name as a string?

Let's say we have the following class. What is the code for the Execute
method? I need a solution that works with the Compact Framework.

public class Executor {

public static Execute(string p_whichFunction) {

// call the function named p_whichFunction
}

private static _function1() {
// processing code
}

private static _function2() {
// processing code
}

private static _function3() {
// processing code
}
}

Thanks in advance for all suggestions.

Joel Finkel
(e-mail address removed)
 
Joel,

Assuming they all have the same signature, you can get the MethodInfo
instance for the method using the string name, and the type of the class
Executor (through reflection). Basically, get the type for Executor, and
call the GetMethod instance, passing the string, as well as the flags for
binding which represent private and static as well.

Then, you can call Invoke on the MethodInfo, passing null for the
instance. Something like this:

public static Execute(string p_whichFunction /* this is a bad parameter
name, by the way */)
{
// Get the type.
Type t = typeof(Executor);

// Get the method info.
MethodInfo methodInfo = t.GetMethod(p_whichFunction,
BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);

// Invoke the method.
methodInfo.Invoke(null, null);
}

I included the public flag in case you change the accessibility of the
methods later.

Also, the p_whichFunction parameter should not be prefixed with "p_".
The public naming guidelines state that you should not use type/locality
identifiers before things that are publically exposed. Also, a more apt
name for the parameter would be "method".

Additionally, I fail to see the use of this method, since the two lines
I gave you are really not that much of a savings at all in terms of coding,
and the reflection APIs are not so obscure.

Hope this helps.
 
Maybe it's just a bad example of what you want to do, but since the methods
are all known to the Executor class, there is no need for reflection in your
example; ignoring the grungy method / parameter names (another poster
already picked that up), what's wrong with:

public static void Execute(string p_whichFunction) {
switch(p_whichFunction) {
case "_function1": _function1(); break;
case "_function2": _function2(); break;
case "_function3": _function3(); break;
default: throw new ArgumentException();
}
}

This also avoids the caller accessing code that they shouldn't be (unless
they do their own reflection).

Marc
 
(you could even make the parameter an enum for a caller-friendly list of the
available options, rather than having to remember a random string)
 
Marc,

What you have provided is exactly what I am now doing. I want to change it
to eliminate a source of coding errors, that is, the switch statement.

The methods are called in a sequence that is not known until runtime. The
sequence is stored in a database. I need to ensure that the strings are
identical in both the database and the code. If I can eliminate the swich
statement, I eliminate a source of potential errors. I need only ensure that
the names stored in the database match the method names; and I can do this in
the UI that is used to maintain the database if I implement the solution
provided by Nicholas.
 
Nicholas,

Thank you. This is exactly what I need. Please see my response to Marc,
which explains my desire to do this. I did not want to include this in my
original post so as to keep it as simple and generic as possible.

/Joel Finkel

Nicholas Paldino said:
Joel,

Assuming they all have the same signature, you can get the MethodInfo
instance for the method using the string name, and the type of the class
Executor (through reflection). Basically, get the type for Executor, and
call the GetMethod instance, passing the string, as well as the flags for
binding which represent private and static as well.

Then, you can call Invoke on the MethodInfo, passing null for the
instance. Something like this:

public static Execute(string p_whichFunction /* this is a bad parameter
name, by the way */)
{
// Get the type.
Type t = typeof(Executor);

// Get the method info.
MethodInfo methodInfo = t.GetMethod(p_whichFunction,
BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);

// Invoke the method.
methodInfo.Invoke(null, null);
}

I included the public flag in case you change the accessibility of the
methods later.

Also, the p_whichFunction parameter should not be prefixed with "p_".
The public naming guidelines state that you should not use type/locality
identifiers before things that are publically exposed. Also, a more apt
name for the parameter would be "method".

Additionally, I fail to see the use of this method, since the two lines
I gave you are really not that much of a savings at all in terms of coding,
and the reflection APIs are not so obscure.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Joel Finkel said:
Is there a way to execute a method if all we know is its name as a string?

Let's say we have the following class. What is the code for the Execute
method? I need a solution that works with the Compact Framework.

public class Executor {

public static Execute(string p_whichFunction) {

// call the function named p_whichFunction
}

private static _function1() {
// processing code
}

private static _function2() {
// processing code
}

private static _function3() {
// processing code
}
}

Thanks in advance for all suggestions.

Joel Finkel
(e-mail address removed)
 
Also, the p_whichFunction parameter should not be prefixed with "p_".
The public naming guidelines state that you should not use type/locality
identifiers before things that are publically exposed. Also, a more apt
name for the parameter would be "method".

Nicholas,

I have been using "p_" to preface parameter names for over 20 years. This
allows me to easily identify parameter variables within the function (okay,
"method").

Actually, when I worked for DEC, I used a modified Hungarian notation for
parameter variables, which allowed me to also easily identify the variable's
type.

In my opinion, the most important thing is to adopt a naming methodology and
stick with it throughout the project.

Thanks again, and regards,
Joel Finkel
 
Joel Finkel said:
Nicholas,

I have been using "p_" to preface parameter names for over 20 years. This
allows me to easily identify parameter variables within the function (okay,
"method").

Actually, when I worked for DEC, I used a modified Hungarian notation for
parameter variables, which allowed me to also easily identify the variable's
type.

In my opinion, the most important thing is to adopt a naming methodology and
stick with it throughout the project.

It's certainly important to adopt one - but I think it's more important
to be consistent with the platform you're working on that with what
you've done on other platforms.

As it is, you'll be calling some methods in PascalCaseLikeThis, and
some with_the_convention_from_C - that's not going to be consistent, is
it?
 
Jon,

An interesting discussion. Unfortunately, I am under an extreme deadline,
so forgive me for asking that we postpone this until we can discuss it over a
beer.

Regards,
Joel Finkel
 
Joel Finkel said:
An interesting discussion. Unfortunately, I am under an extreme deadline,
so forgive me for asking that we postpone this until we can discuss it over a
beer.

No problem - definitely something to think about for the next project
though, if nothing else :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top