fork download
  1. using System;
  2. using System.Linq;
  3. using System.Runtime.CompilerServices;
  4. using Microsoft.CSharp.RuntimeBinder; // Requires reference to Microsoft.CSharp
  5.  
  6. public class ImplicitTest
  7. {
  8. public double Val { get; set; }
  9.  
  10. public ImplicitTest(double val)
  11. {
  12. this.Val = val;
  13. }
  14.  
  15. public static implicit operator int(ImplicitTest d)
  16. {
  17. return (int)d.Val;
  18. }
  19. }
  20.  
  21. public class TestClass
  22. {
  23. public int Val { get; set; }
  24.  
  25. public TestClass(int val = 5)
  26. {
  27. this.Val = val;
  28. }
  29.  
  30. public TestClass(int val1, int val2)
  31. {
  32. this.Val = val1 + val2;
  33. }
  34.  
  35. public TestClass(int val1, int val2, int val3, int val4, int val5, int val6, int val7, int val8, int val9, int val10, int val11, int val12, int val13, int val14)
  36. {
  37. this.Val = val1 + val2 + val3 + val4 + val5 + val6 + val7 + val8 + val9 + val10 + val11 + val12 + val13 + val14;
  38. }
  39. }
  40.  
  41. public static class DynamicFactory
  42. {
  43. private static readonly CallSiteBinder callsiteBinder0 = Binder.InvokeConstructor(
  44. CSharpBinderFlags.None,
  45. typeof(DynamicFactory),
  46. // It is OK to have too many arguments :-)
  47. new CSharpArgumentInfo[]
  48. {
  49. CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.IsStaticType | CSharpArgumentInfoFlags.UseCompileTimeType, null), // 0 parameters
  50. });
  51.  
  52. private static readonly CallSiteBinder callsiteBinder = Binder.InvokeConstructor(
  53. CSharpBinderFlags.None,
  54. typeof(DynamicFactory),
  55. // It is OK to have too many arguments :-)
  56. // Note that this "feature" doesn't work correctly with Mono in the
  57. // case of 0 arguments
  58. new CSharpArgumentInfo[]
  59. {
  60. CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.IsStaticType | CSharpArgumentInfoFlags.UseCompileTimeType, null), // 0 parameters
  61. CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null), // 1 parameter
  62. CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null), // 2 parameters
  63. CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
  64. CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
  65. CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
  66. CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
  67. CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
  68. CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
  69. CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
  70. CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
  71. CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
  72. CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
  73. CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
  74. CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null), // 14 parameters
  75. });
  76.  
  77. // Quirk of Mono with 0 arguments. See callsiteBinder0
  78. private static readonly CallSite<Func<CallSite, Type, object>> CallSite0 = CallSite<Func<CallSite, Type, object>>.Create(callsiteBinder0);
  79.  
  80. private static readonly CallSite<Func<CallSite, Type, object, object>> CallSite1 = CallSite<Func<CallSite, Type, object, object>>.Create(callsiteBinder);
  81. private static readonly CallSite<Func<CallSite, Type, object, object, object>> CallSite2 = CallSite<Func<CallSite, Type, object, object, object>>.Create(callsiteBinder);
  82. private static readonly CallSite<Func<CallSite, Type, object, object, object, object>> CallSite3 = CallSite<Func<CallSite, Type, object, object, object, object>>.Create(callsiteBinder);
  83. private static readonly CallSite<Func<CallSite, Type, object, object, object, object, object>> CallSite4 = CallSite<Func<CallSite, Type, object, object, object, object, object>>.Create(callsiteBinder);
  84. private static readonly CallSite<Func<CallSite, Type, object, object, object, object, object, object>> CallSite5 = CallSite<Func<CallSite, Type, object, object, object, object, object, object>>.Create(callsiteBinder);
  85. private static readonly CallSite<Func<CallSite, Type, object, object, object, object, object, object, object>> CallSite6 = CallSite<Func<CallSite, Type, object, object, object, object, object, object, object>>.Create(callsiteBinder);
  86. private static readonly CallSite<Func<CallSite, Type, object, object, object, object, object, object, object, object>> CallSite7 = CallSite<Func<CallSite, Type, object, object, object, object, object, object, object, object>>.Create(callsiteBinder);
  87. private static readonly CallSite<Func<CallSite, Type, object, object, object, object, object, object, object, object, object>> CallSite8 = CallSite<Func<CallSite, Type, object, object, object, object, object, object, object, object, object>>.Create(callsiteBinder);
  88. private static readonly CallSite<Func<CallSite, Type, object, object, object, object, object, object, object, object, object, object>> CallSite9 = CallSite<Func<CallSite, Type, object, object, object, object, object, object, object, object, object, object>>.Create(callsiteBinder);
  89. private static readonly CallSite<Func<CallSite, Type, object, object, object, object, object, object, object, object, object, object, object>> CallSite10 = CallSite<Func<CallSite, Type, object, object, object, object, object, object, object, object, object, object, object>>.Create(callsiteBinder);
  90. private static readonly CallSite<Func<CallSite, Type, object, object, object, object, object, object, object, object, object, object, object, object>> CallSite11 = CallSite<Func<CallSite, Type, object, object, object, object, object, object, object, object, object, object, object, object>>.Create(callsiteBinder);
  91. private static readonly CallSite<Func<CallSite, Type, object, object, object, object, object, object, object, object, object, object, object, object, object>> CallSite12 = CallSite<Func<CallSite, Type, object, object, object, object, object, object, object, object, object, object, object, object, object>>.Create(callsiteBinder);
  92. private static readonly CallSite<Func<CallSite, Type, object, object, object, object, object, object, object, object, object, object, object, object, object, object>> CallSite13 = CallSite<Func<CallSite, Type, object, object, object, object, object, object, object, object, object, object, object, object, object, object>>.Create(callsiteBinder);
  93. private static readonly CallSite<Func<CallSite, Type, object, object, object, object, object, object, object, object, object, object, object, object, object, object, object>> CallSite14 = CallSite<Func<CallSite, Type, object, object, object, object, object, object, object, object, object, object, object, object, object, object, object>>.Create(callsiteBinder);
  94.  
  95. public static object Create(string typeName, params object[] args)
  96. {
  97. return Create(Type.GetType(typeName), args);
  98. }
  99.  
  100. public static object Create(Type type, params object[] args)
  101. {
  102. if (type == null)
  103. {
  104. throw new ArgumentNullException("type");
  105. }
  106.  
  107. if (args == null)
  108. {
  109. args = new object[0];
  110. }
  111.  
  112. object obj;
  113.  
  114. switch (args.Length)
  115. {
  116. case 0:
  117. // Quirk of Mono with 0 arguments. See callsiteBinder0
  118. obj = CallSite0.Target(CallSite0, type);
  119. break;
  120.  
  121. case 1:
  122. obj = CallSite1.Target(CallSite1, type, args[0]);
  123. break;
  124.  
  125. case 2:
  126. obj = CallSite2.Target(CallSite2, type, args[0], args[1]);
  127. break;
  128.  
  129. case 3:
  130. obj = CallSite3.Target(CallSite3, type, args[0], args[1], args[2]);
  131. break;
  132.  
  133. case 4:
  134. obj = CallSite4.Target(CallSite4, type, args[0], args[1], args[2], args[3]);
  135. break;
  136.  
  137. case 5:
  138. obj = CallSite5.Target(CallSite5, type, args[0], args[1], args[2], args[3], args[4]);
  139. break;
  140.  
  141. case 6:
  142. obj = CallSite6.Target(CallSite6, type, args[0], args[1], args[2], args[3], args[4], args[5]);
  143. break;
  144.  
  145. case 7:
  146. obj = CallSite7.Target(CallSite7, type, args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
  147. break;
  148.  
  149. case 8:
  150. obj = CallSite8.Target(CallSite8, type, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]);
  151. break;
  152.  
  153. case 9:
  154. obj = CallSite9.Target(CallSite9, type, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8]);
  155. break;
  156.  
  157. case 10:
  158. obj = CallSite10.Target(CallSite10, type, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9]);
  159. break;
  160.  
  161. case 11:
  162. obj = CallSite11.Target(CallSite11, type, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9], args[10]);
  163. break;
  164.  
  165. case 12:
  166. obj = CallSite12.Target(CallSite12, type, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9], args[10], args[11]);
  167. break;
  168.  
  169. case 13:
  170. obj = CallSite13.Target(CallSite13, type, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9], args[10], args[11], args[12]);
  171. break;
  172.  
  173. case 14:
  174. obj = CallSite14.Target(CallSite14, type, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9], args[10], args[11], args[12], args[13]);
  175. break;
  176.  
  177. default:
  178. throw new ArgumentException("Too many parameters");
  179. }
  180.  
  181. return obj;
  182. }
  183. }
  184.  
  185. public class Program
  186. {
  187. public static void Main()
  188. {
  189. try
  190. {
  191. Type monoRuntime = Type.GetType("Mono.Runtime");
  192.  
  193. if (monoRuntime != null)
  194. {
  195. System.Reflection.MethodInfo displayName = monoRuntime.GetMethod("GetDisplayName", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);
  196.  
  197. if (displayName != null)
  198. {
  199. Console.WriteLine("Mono version {0}", displayName.Invoke(null, null));
  200. }
  201. }
  202.  
  203. TestClass tc0 = (TestClass)DynamicFactory.Create("TestClass");
  204. TestClass tc1 = (TestClass)DynamicFactory.Create("TestClass", new ImplicitTest(1.0));
  205. TestClass tc1b = (TestClass)DynamicFactory.Create("TestClass", 1);
  206. TestClass tc2 = (TestClass)DynamicFactory.Create("TestClass", new ImplicitTest(1.0), new ImplicitTest(2.0));
  207. TestClass tc14 = (TestClass)DynamicFactory.Create("TestClass", Enumerable.Range(0, 14).Select(x => new ImplicitTest((double)x)).ToArray());
  208.  
  209. Console.WriteLine(tc0.Val);
  210. Console.WriteLine(tc1.Val);
  211. Console.WriteLine(tc1b.Val);
  212. Console.WriteLine(tc2.Val);
  213. Console.WriteLine(tc14.Val);
  214. }
  215. catch (Exception ex)
  216. {
  217. Console.WriteLine(ex);
  218. }
  219. }
  220. }
Success #stdin #stdout 0.44s 30952KB
stdin
Standard input is empty
stdout
Mono version 4.0.2 (Stable 4.0.2.5/c99aa0c Wed Jun 24 10:12:58 UTC 2015)
5
1
1
3
91