Skip to content

Instantly share code, notes, and snippets.

@txdv
Created April 14, 2012 12:39
Show Gist options
  • Save txdv/2384144 to your computer and use it in GitHub Desktop.
Save txdv/2384144 to your computer and use it in GitHub Desktop.
Dynamic delegates!
using System;
using System.Reflection;
using System.Linq;
namespace testing
{
class DynamicDelegate
{
public MethodInfo Method { get; protected set; }
public string Name { get; protected set; }
public int Position { get; protected set; }
internal Action<DynamicDelegate, Type[], object[]> Action { get; set; }
DynamicDelegate(MethodInfo m, int i, string name, Action<DynamicDelegate, Type[], object[]> callback)
{
Method = m;
Position = i;
Name = name;
Action = callback;
}
private static void Callback<T1>(DynamicDelegate i, T1 value1)
{
OnCallback(i, new [] { typeof(T1) }, new object[] { value1 });
}
private static void Callback<T1, T2>(DynamicDelegate i, T1 value1, T2 value2)
{
OnCallback(i, new [] { typeof(T1), typeof(T2) }, new object[] { value1, value2 });
}
private static void Callback<T1, T2, T3>(DynamicDelegate i, T1 value1, T2 value2, T3 value3)
{
OnCallback(i, new [] { typeof(T1), typeof(T2), typeof(T3) }, new object[] { value1, value2, value3 });
}
private static void Callback<T1, T2, T3, T4>(DynamicDelegate i, T1 value1, T2 value2, T3 value3, T4 value4)
{
OnCallback(i, new [] { typeof(T1), typeof(T2), typeof(T3), typeof(T4) }, new object[] { value1, value2, value3, value4 });
}
private static void Callback<T1, T2, T3, T4, T5>(DynamicDelegate i, T1 value1, T2 value2, T3 value3, T4 value4, T5 value5)
{
OnCallback(i, new [] { typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5) }, new object[] { value1, value2, value3, value4, value5 });
}
private static void Callback<T1, T2, T3, T4, T5, T6>(DynamicDelegate i, T1 value1, T2 value2, T3 value3, T4 value4, T5 value5, T6 value6)
{
OnCallback(i, new [] { typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6) }, new object[] { value1, value2, value3, value4, value5, value6 });
}
private static void Callback<T1, T2, T3, T4, T5, T6, T7>(DynamicDelegate i, T1 value1, T2 value2, T3 value3, T4 value4, T5 value5, T6 value6, T7 value7)
{
OnCallback(i, new [] { typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7) }, new object[] { value1, value2, value3, value4, value5, value6, value7 });
}
private static void Callback<T1, T2, T3, T4, T5, T6, T7, T8>(DynamicDelegate i, T1 value1, T2 value2, T3 value3, T4 value4, T5 value5, T6 value6, T7 value7, T8 value8)
{
OnCallback(i, new [] { typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8) }, new object[] { value1, value2, value3, value4, value5, value6, value7, value8 });
}
private static void OnCallback(DynamicDelegate info, Type[] types, object[] objects)
{
info.Action(info, types, objects);
}
public static void Invoke(MethodInfo mi, Action<DynamicDelegate, Type[], object[]> callback)
{
Invoke(null, mi, callback);
}
public static void Invoke(object obj, MethodInfo mi, Action<DynamicDelegate, Type[], object[]> callback)
{
var @params = mi.GetParameters();
object[] args = new object[@params.Length];
for (int i = 0; i < @params.Length; i++) {
var param = @params[i];
var method = typeof(DynamicDelegate).GetMethods(BindingFlags.NonPublic | BindingFlags.Static).Where(m => m.Name == "Callback")
.Where(m => m.GetGenericArguments().Length == param.ParameterType.GetGenericArguments().Length)
.First().MakeGenericMethod(param.ParameterType.GetGenericArguments());
args[i] = Delegate.CreateDelegate(param.ParameterType, new DynamicDelegate(mi, i, @params[i].Name, callback), method);
}
mi.Invoke(obj, args);
}
}
public class MainClass
{
public static void Main(string[] args)
{
DynamicDelegate.Invoke(typeof(MainClass).GetMethod("SomeMethod"), (di, types, objects) => {
Console.WriteLine("Delegate: {0}", di.Name);
for (int i = 0; i < types.Length; i++) {
Console.WriteLine("Type: {0}, Value: {1}", types[i], objects[i]);
}
Console.WriteLine();
});
}
public static void SomeMethod(Action<int, string> callback, Action<int, string, int> callback2, Action<float, int, string, int> callback3)
{
Random r = new Random();
callback(r.Next() % 200, "Hello World!");
callback2(r.Next() % 200, "goodbye world", r.Next() % 200);
callback3(6.9f, r.Next() % 200, "i am mad", r.Next() % 200);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment