I suppose in some ways either (or both) Delegate or MethodInfo qualify for this title. However, neither provide the syntactic niceness that I'm looking for. So, in short, Is there some way that I can write the following:
FunctionPointer foo = // whatever, create the function pointer using mechanisms
foo();
I can't use a solid delegate (ie, using the delegate keyword to declare a delegate type) because there is no way of knowing till runtime the exact parameter list. For reference, here's what I've been toying with in LINQPad currently, where B will be (mostly) user generated code, and so will Main, and hence for nicety to my users, I'm trying to remove the .Call:
void Main()
{
A foo = new B();
foo["SomeFuntion"].Call();
}
// Define other methods and classes here
interface IFunction {
void Call();
void Call(params object[] parameters);
}
class A {
private class Function : IFunction {
private MethodInfo _mi;
private A _this;
public Function(A #this, MethodInfo mi) {
_mi = mi;
_this = #this;
}
public void Call() { Call(null); }
public void Call(params object[] parameters) {
_mi.Invoke(_this, parameters);
}
}
Dictionary<string, MethodInfo> functions = new Dictionary<string, MethodInfo>();
public A() {
List<MethodInfo> ml = new List<MethodInfo>(this.GetType().GetMethods());
foreach (MethodInfo mi in typeof(Object).GetMethods())
{
for (int i = 0; i < ml.Count; i++)
{
if (ml[i].Name == mi.Name)
ml.RemoveAt(i);
}
}
foreach (MethodInfo mi in ml)
{
functions[mi.Name] = mi;
}
}
public IFunction this[string function] {
get {
if (!functions.ContainsKey(function))
throw new ArgumentException();
return new Function(this, functions[function]);
}
}
}
sealed class B : A {
public void SomeFuntion() {
Console.WriteLine("SomeFunction called.");
}
}
You say you want to keep the number and type of parameters open, but you can do that with a delgate:
public delegate object DynamicFunc(params object[] parameters);
This is exactly the same thing you currently have. Try this:
class Program
{
static void Main(string[] args)
{
DynamicFunc f = par =>
{
foreach (var p in par)
Console.WriteLine(p);
return null;
};
f(1, 4, "Hi");
}
}
You can think of an instance-method delegate as very similar to your Function class: an object an a MethodInfo. So there's no need to rewrite it.
Also function pointers in C and C++ are not any closer to what you need: they cannot be bound to an object instance and function, and also they are statically typed, not dynamically typed.
If you want to "wrap" any other method in a DynamicFunc delegate, try this:
public static DynamicFunc MakeDynamicFunc(object target, MethodInfo method)
{
return par => method.Invoke(target, par);
}
public static void Foo(string s, int n)
{
Console.WriteLine(s);
Console.WriteLine(n);
}
and then:
DynamicFunc f2 = MakeDynamicFunc(null, typeof(Program).GetMethod("Foo"));
f2("test", 100);
Note that I'm using a static method Foo so I pass null for the instance, but if it was an instance method, I'd be passing the object to bind to. Program happens to be the class my static methods are defined in.
Of course, if you pass the wrong argument types then you get errors at runtime. I'd probably look for a way to design your program so that as much type information is captured at compile time as possible.
Here's another bit of code you could use; Reflection is rather slow, so if you expect your Dynamic function calls to be called frequently, you don't want method.Invoke inside the delegate:
public delegate void DynamicAction(params object[] parameters);
static class DynamicActionBuilder
{
public static void PerformAction0(Action a, object[] pars) { a(); }
public static void PerformAction1<T1>(Action<T1> a, object[] p) {
a((T1)p[0]);
}
public static void PerformAction2<T1, T2>(Action<T1, T2> a, object[] p) {
a((T1)p[0], (T2)p[1]);
}
//etc...
public static DynamicAction MakeAction(object target, MethodInfo mi) {
Type[] typeArgs =
mi.GetParameters().Select(pi => pi.ParameterType).ToArray();
string perfActName = "PerformAction" + typeArgs.Length;
MethodInfo performAction =
typeof(DynamicActionBuilder).GetMethod(perfActName);
if (typeArgs.Length != 0)
performAction = performAction.MakeGenericMethod(typeArgs);
Type actionType = performAction.GetParameters()[0].ParameterType;
Delegate action = Delegate.CreateDelegate(actionType, target, mi);
return (DynamicAction)Delegate.CreateDelegate(
typeof(DynamicAction), action, performAction);
}
}
And you could use it like this:
static class TestDab
{
public static void PrintTwo(int a, int b) {
Console.WriteLine("{0} {1}", a, b);
Trace.WriteLine(string.Format("{0} {1}", a, b));//for immediate window.
}
public static void PrintHelloWorld() {
Console.WriteLine("Hello World!");
Trace.WriteLine("Hello World!");//for immediate window.
}
public static void TestIt() {
var dynFunc = DynamicActionBuilder.MakeAction(null,
typeof(TestDab).GetMethod("PrintTwo"));
dynFunc(3, 4);
var dynFunc2 = DynamicActionBuilder.MakeAction(null,
typeof(TestDab).GetMethod("PrintHelloWorld"));
dynFunc2("extraneous","params","allowed"); //you may want to check this.
}
}
This will be quite a bit faster; each dynamic call will involve 1 typecheck per param, 2 delegate calls, and one array construction due to the params-style passing.
Related
How do I call a static method from a Type, assuming I know the value of the Type variable and the name of the static method?
public class FooClass {
public static FooMethod() {
//do something
}
}
public class BarClass {
public void BarMethod(Type t) {
FooClass.FooMethod() //works fine
if (t is FooClass) {
t.FooMethod(); //should call FooClass.FooMethod(); compile error
}
}
}
So, given a Type t, the objective is to call FooMethod() on the class that is of Type t. Basically I need to reverse the typeof() operator.
You need to call MethodInfo.Invoke method:
public class BarClass {
public void BarMethod(Type t) {
FooClass.FooMethod(); //works fine
if (t == typeof(FooClass)) {
t.GetMethod("FooMethod").Invoke(null, null); // (null, null) means calling static method with no parameters
}
}
}
Of course in the above example you might as well call FooClass.FooMethod as there is no point using reflection for that. The following sample makes more sense:
public class BarClass {
public void BarMethod(Type t, string method) {
var methodInfo = t.GetMethod(method);
if (methodInfo != null) {
methodInfo.Invoke(null, null); // (null, null) means calling static method with no parameters
}
}
}
public class Foo1Class {
static public Foo1Method(){}
}
public class Foo2Class {
static public Foo2Method(){}
}
//Usage
new BarClass().BarMethod(typeof(Foo1Class), "Foo1Method");
new BarClass().BarMethod(typeof(Foo2Class), "Foo2Method");
Note, that as 10 years have passed. Personally, I would add extension method:
public static TR Method<TR>(this Type t, string method, object obj = null, params object[] parameters)
=> (TR)t.GetMethod(method)?.Invoke(obj, parameters);
and then I could call it with:
var result = typeof(Foo1Class).Method<string>(nameof(Foo1Class.Foo1Method));
Check into the MethodInfo class and the GetMethod() methods on Type.
There are a number of different overloads for different situations.
I am trying to call a method that takes in a function, but using relection. I've gotten it to work when the method is parameterless but I can't figure out how to invoke it when there are arguments. This is a contrived simplified example, but this boils down the problem. I will not know the arguments to Add until runtime.
Any pointers? Do I have to use expression trees? Is there an easier way to do this?
public void Main()
{
//works
CallFunction(typeof (Processor), "Count");
//I don't understand what I need to modify to make add work
CallFunction(typeof (Processor), "Add");
}
public void CallFunction(Type type, string methodToCall)
{
var targetMethod = type.GetMethod(methodToCall);
var constructedType = typeof (MethodCaller<>).MakeGenericType(type);
dynamic target = Activator.CreateInstance(constructedType);
var method = constructedType.GetMethod("Do").MakeGenericMethod(targetMethod.ReturnType);
var func = typeof (Func<,>).MakeGenericType(type, targetMethod.ReturnType);
var toCall = Delegate.CreateDelegate(func, targetMethod);
method.Invoke(target, new object[] { toCall });
}
public class Processor
{
public int Count()
{
return 1;
}
public int Add(int toAdd)
{
return 1 + toAdd;
}
}
public class MethodCaller<TParm> where TParm : new()
{
public TResult Do<TResult>(Func<TParm, TResult> func)
{
return func(new TParm());
}
}
Like type.InvokeMember(method_name, System.Reflection.BindingFlags.InvokeMethod, null, type_instance, new object[] { param1, param2, param3 }); ?
https://msdn.microsoft.com/en-us/library/66btctbe(v=vs.110).aspx
Actually whole CallFunction method can be simplified like this:
public void CallFunction(Type type, string methodToCall, params object[] args)
{
// Why this part is so complex? Do I miss something?
//var constructedType = typeof (MethodCaller<>).MakeGenericType(type);
//dynamic target = Activator.CreateInstance(constructedType);
var target = Activator.CreateInstance(type);
var result = type.InvokeMember(method_name, System.Reflection.BindingFlags.InvokeMethod, null, target, args);
// ... do something with result if you need ...
}
If you need MethodCaller.Do, but can sacrifice types on signature (or some performance on boxing/unboxing for DoTyped)
public void CallFunction(Type type, string methodToCall, params object[] args)
{
var delegate_wrapper = new Func<object, object>(
instance => type.InvokeMember(methodToCall, BindingFlags.InvokeMethod, null, instance, args)
);
var target_method = type.GetMethod(methodToCall);
var mc_custom_type = typeof (MethodCaller<>).MakeGenericType(type);
var mc_instance = Activator.CreateInstance(mc_custom_type);
var mc_custom_method = mc_custom_type.GetMethod("Do").MakeGenericMethod(target_method.ReturnType);
mc_custom_method.Invoke(mc_instance, new object[] { delegate_wrapper });
}
public class MethodCaller<TParm> where TParm : new()
{
public TResult DoTyped<TResult>(Func<TParm, TResult> func)
{
return Do<TResult>(oinstance=>func((TParm)oinstance));
}
public TResult Do<TResult>(Func<object, object> func)
{
Console.WriteLine("I AM DO");
return (TResult)func(new TParm());
}
}
Have you tried looking at Impromptu framework. It is primarily for duck typing but the library provide rather slick api to access methods and pass arguments.
https://github.com/ekonbenefits/impromptu-interface/wiki/UsageReallyLateBinding
I want to have a class that will execute any external method, like this:
class CrazyClass
{
//other stuff
public AnyReturnType Execute(AnyKindOfMethod Method, object[] ParametersForMethod)
{
//more stuff
return Method(ParametersForMethod) //or something like that
}
}
Is this possible? Is there a delegate that takes any method signature?
You can do this a different way by Func<T> and closures:
public T Execute<T>(Func<T> method)
{
// stuff
return method();
}
The caller can then use closures to implement it:
var result = yourClassInstance.Execute(() => SomeMethod(arg1, arg2, arg3));
The advantage here is that you allow the compiler to do the hard work for you, and the method calls and return value are all type safe, provide intellisense, etc.
I think you are better off using reflections in this case, as you will get exactly what you asked for in the question - any method (static or instance), any parameters:
public object Execute(MethodInfo mi, object instance = null, object[] parameters = null)
{
return mi.Invoke(instance, parameters);
}
It's System.Reflection.MethodInfo class.
Kinda depends on why you want to do this in the first place...I would do this using the Func generic so that the CrazyClass can still be ignorant of the parameters.
class CrazyClass
{
//other stuff
public T Execute<T>(Func<T> Method)
{
//more stuff
return Method();//or something like that
}
}
class Program
{
public static int Foo(int a, int b)
{
return a + b;
}
static void Main(string[] args)
{
CrazyClass cc = new CrazyClass();
int someargs1 = 20;
int someargs2 = 10;
Func<int> method = new Func<int>(()=>Foo(someargs1,someargs2));
cc.Execute(method);
//which begs the question why the user wouldn't just do this:
Foo(someargs1, someargs2);
}
}
public static void AnyFuncExecutor(Action a)
{
try
{
a();
}
catch (Exception exception)
{
throw;
}
}
How do I call a static method from a Type, assuming I know the value of the Type variable and the name of the static method?
public class FooClass {
public static FooMethod() {
//do something
}
}
public class BarClass {
public void BarMethod(Type t) {
FooClass.FooMethod() //works fine
if (t is FooClass) {
t.FooMethod(); //should call FooClass.FooMethod(); compile error
}
}
}
So, given a Type t, the objective is to call FooMethod() on the class that is of Type t. Basically I need to reverse the typeof() operator.
You need to call MethodInfo.Invoke method:
public class BarClass {
public void BarMethod(Type t) {
FooClass.FooMethod(); //works fine
if (t == typeof(FooClass)) {
t.GetMethod("FooMethod").Invoke(null, null); // (null, null) means calling static method with no parameters
}
}
}
Of course in the above example you might as well call FooClass.FooMethod as there is no point using reflection for that. The following sample makes more sense:
public class BarClass {
public void BarMethod(Type t, string method) {
var methodInfo = t.GetMethod(method);
if (methodInfo != null) {
methodInfo.Invoke(null, null); // (null, null) means calling static method with no parameters
}
}
}
public class Foo1Class {
static public Foo1Method(){}
}
public class Foo2Class {
static public Foo2Method(){}
}
//Usage
new BarClass().BarMethod(typeof(Foo1Class), "Foo1Method");
new BarClass().BarMethod(typeof(Foo2Class), "Foo2Method");
Note, that as 10 years have passed. Personally, I would add extension method:
public static TR Method<TR>(this Type t, string method, object obj = null, params object[] parameters)
=> (TR)t.GetMethod(method)?.Invoke(obj, parameters);
and then I could call it with:
var result = typeof(Foo1Class).Method<string>(nameof(Foo1Class.Foo1Method));
Check into the MethodInfo class and the GetMethod() methods on Type.
There are a number of different overloads for different situations.
Assume we have legacy classes, that can't be modified:
class Foo
{
public void Calculate(int a) { }
}
class Bar
{
public void Compute(int a) {}
}
I want to write a helper with such signature:
void Calc(object obj, int a);
Notice, that the first argument is of type 'object'. The test code should be some like this:
ExampleX.Calc((object)new Foo(), 0);
ExampleX.Calc((object)new Bar(), 0);
The question is, what implementation you can imagine in addition to these:
// Using If/then
class Example1
{
public static void Calc(object obj, int a)
{
if (obj is Foo)
((Foo)obj).Calculate(a);
else if (obj is Bar)
((Bar)obj).Compute(a);
}
}
// Using reflection
class Example2
{
private static Dictionary<Type, MethodInfo> _methods = new Dictionary<Type, MethodInfo>();
static Example2()
{
_methods.Add(typeof(Foo), typeof(Foo).GetMethod("Calculate"));
_methods.Add(typeof(Bar), typeof(Bar).GetMethod("Compute"));
}
public static void Calc(object obj, int a)
{
_methods[obj.GetType()].Invoke(obj, new object[] { a });
}
}
// Using delegates
class Example3
{
private delegate void CalcDelegate(object obj, int a);
private static Dictionary<Type, CalcDelegate> _methods = new Dictionary<Type, CalcDelegate>();
static Example3()
{
_methods.Add(typeof(Foo), (o, a) => ((Foo)o).Calculate(a));
_methods.Add(typeof(Bar), (o, a) => ((Bar)o).Compute(a));
}
public static void Calc(object obj, int a)
{
_methods[obj.GetType()](obj, a);
}
}
// Using Reflection + overloaded methods
class Example4
{
private delegate void CalcDelegate(object obj, int a);
public static void Calc(object obj, int a)
{
Type[] types = new Type[] {
obj.GetType(), typeof(int)
};
typeof(Example4).GetMethod("Calc", types).Invoke(null, new object[] { obj, a });
}
public static void Calc(Foo obj, int a)
{
obj.Calculate(a);
}
public static void Calc(Bar obj, int a)
{
obj.Compute(a);
}
}
Thanks!
Use extension methods to essentially add a new function to an existing type.
http://msdn.microsoft.com/en-us/library/bb383977.aspx
This is how I would write the solution. It reduces the risk of type safety problems in the code and eliminates reflection.
class Example2
{
private static Dictionary<Type, Action<object,int>> _methods = new Dictionary<Type, Action<object,int>>();
static Example2()
{
Add<Foo>( (f,a) => f.Calculate(a) );
Add<Bar>( (b,a) => b.Compute(a) );
}
public static void Calc<TSource>(TSource source, int a)
{
_methods[typeof(TSource)](source,a);
}
public static void Add<TSource>(Action<TSource,int> del)
{
Action<object,int> wrapper = (x,i) => { del((TSource)x, i); };
_methods[typeof(TSource)] = wrapper;
}
}
you could always use the adapter pattern to implement the unchangeable legacy objects, without breaking any objects dependant on its functionality, while still being ableto implement your own (new) functionality to the object.
I would go for example 1, because its the simplest one and most obvious.
I would use Example 2 only if you expect new types of objects with one of these two methods, and example 3 only if you have a lot (tens if not hundreds) of objects and performance starts being an issue.
Edit: Or extension methods if you are .Net 3