barakza
Joined: 03 Aug 2010 Posts: 1
|
Posted: Tue Aug 03, 2010 7:32 am Post subject: calling a method using a string |
|
|
Hi Everybody,
I'd like to know if there's a PInvoke method I can use that will allow me to call a method by giving it's name as a string?
i.e., if I send a string "foo" , I'd like to invoke foo() function.
(I know I can use Reflection in c#, however, I'm looking for another way of solving it).
Thanks,
Barak |
|
Brian Donahue
Joined: 23 Aug 2004 Posts: 6369 Location: Red Gate Software
|
Posted: Tue Aug 03, 2010 10:11 am Post subject: |
|
|
Noop, I'm afraid I only know "the hard way" of binding to a method. For example:
| Code: |
Assembly a = Assembly.Load("RedGate.Foo.Bar");
Type utilsType = a.GetType("x");
string ret = String.Empty;
string strOut = (string)utilsType.InvokeMember("a",
BindingFlags.Static | BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Public, new StringBinder(), utilsType, null);
return strOut;
|
Note that in this case, method "a" has several overloads and I am interested only in the one that returns a string, so I wrote the "StringBinder" class:
| Code: |
/// <summary>
/// This class is used to make sure an invoked member returns a String.
/// If you do not use this binder in InvokeMethod, you will get an
/// AmbiguousMethodException, for instance when there are two methods: W.b():boolean and W.b():String
/// </summary>
public class StringBinder : Binder
{
/// <summary>
/// Placeholder
/// </summary>
/// <param name="bindingAttr"></param>
/// <param name="match"></param>
/// <param name="value"></param>
/// <param name="culture"></param>
/// <returns></returns>
public override FieldInfo BindToField(BindingFlags bindingAttr,
FieldInfo[] match, object value,
CultureInfo culture)
{
if (match.Length > 1) throw new AmbiguousMatchException();
return match[0];
}
public override MethodBase BindToMethod(BindingFlags bindingAttr,
MethodBase[] match, ref object[] args,
ParameterModifier[] modifiers,
CultureInfo culture,
string[] names, out object state)
{
state = null;
foreach (MethodBase m in match)
{
if (m.ToString().Contains("String " + m.Name)) return m;
}
throw new AmbiguousMatchException();
}
public override void ReorderArgumentArray(ref object[] args,
object state)
{
//none needed
}
/// <summary>
/// Placeholder
/// </summary>
/// <param name="bindingAttr"></param>
/// <param name="match"></param>
/// <param name="types"></param>
/// <param name="modifiers"></param>
/// <returns></returns>
public override MethodBase SelectMethod(BindingFlags bindingAttr,
MethodBase[] match, Type[] types, ParameterModifier[] modifiers)
{
if (match.Length > 1) throw new AmbiguousMatchException();
return match[0];
}
/// <summary>
/// Placeholder
/// </summary>
/// <param name="bindingAttr"></param>
/// <param name="match"></param>
/// <param name="returnType"></param>
/// <param name="indexes"></param>
/// <param name="modifiers"></param>
/// <returns></returns>
public override PropertyInfo SelectProperty(BindingFlags bindingAttr,
PropertyInfo[] match, Type returnType, Type[] indexes,
ParameterModifier[] modifiers)
{
if (match.Length > 1) throw new AmbiguousMatchException();
return match[0];
}
public override object ChangeType(object value, Type type,
CultureInfo culture)
{
if (value.GetType() == typeof(string))
{
//Console.WriteLine("Change '{0}' to type {1}", value, type);
return Convert.ChangeType(value, type);
}
return value;
}
}
|
_________________ Brian Donahue
Technical Support
Red Gate Software Ltd.
44 (0)870 160 0037 ext 8521
US and CAN 1-866-RED GATE ext 8521 |
|