Created
          April 14, 2012 12:39 
        
      - 
      
- 
        Save txdv/2384144 to your computer and use it in GitHub Desktop. 
    Dynamic delegates!
  
        
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | 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