DynamicMethodTest.cs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616
  1. //
  2. // DynamicMethodTest.cs - NUnit Test Cases for the DynamicMethod class
  3. //
  4. // Gert Driesen ([email protected])
  5. // Konrad Kruczynski
  6. //
  7. // (C) 2006 Novell
  8. using System;
  9. using System.Reflection;
  10. using System.Reflection.Emit;
  11. using System.Runtime.InteropServices;
  12. using System.Text;
  13. using System.Diagnostics;
  14. using System.Runtime.ExceptionServices;
  15. using NUnit.Framework;
  16. namespace MonoTests.System.Reflection.Emit
  17. {
  18. [TestFixture]
  19. public class DynamicMethodTest
  20. {
  21. private delegate int HelloInvoker (string msg);
  22. [Test]
  23. public void Constructor1_Name_Null ()
  24. {
  25. try {
  26. new DynamicMethod (null,
  27. typeof (void),
  28. new Type[] { typeof (string) },
  29. typeof (DynamicMethodTest).Module);
  30. Assert.Fail ("#1");
  31. } catch (ArgumentNullException ex) {
  32. Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
  33. Assert.AreEqual ("name", ex.ParamName, "#3");
  34. Assert.IsNull (ex.InnerException, "#4");
  35. }
  36. }
  37. [Test]
  38. public void Constructor2_Name_Null ()
  39. {
  40. try {
  41. new DynamicMethod (null,
  42. typeof (void),
  43. new Type[] { typeof (string) },
  44. typeof (DynamicMethodTest));
  45. Assert.Fail ("#1");
  46. } catch (ArgumentNullException ex) {
  47. Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
  48. Assert.AreEqual ("name", ex.ParamName, "#3");
  49. Assert.IsNull (ex.InnerException, "#4");
  50. }
  51. }
  52. [Test]
  53. public void Constructor3_Name_Null ()
  54. {
  55. try {
  56. new DynamicMethod (null,
  57. typeof (void),
  58. new Type[] { typeof (string) },
  59. typeof (DynamicMethodTest).Module, true);
  60. Assert.Fail ("#1");
  61. } catch (ArgumentNullException ex) {
  62. Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
  63. Assert.AreEqual ("name", ex.ParamName, "#3");
  64. Assert.IsNull (ex.InnerException, "#4");
  65. }
  66. }
  67. [Test]
  68. public void Constructor4_Name_Null ()
  69. {
  70. try {
  71. new DynamicMethod (null,
  72. typeof (void),
  73. new Type[] { typeof (string) },
  74. typeof (DynamicMethodTest), true);
  75. Assert.Fail ("#1");
  76. } catch (ArgumentNullException ex) {
  77. Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
  78. Assert.AreEqual ("name", ex.ParamName, "#3");
  79. Assert.IsNull (ex.InnerException, "#4");
  80. }
  81. }
  82. [Test]
  83. public void Constructor5_Name_Null ()
  84. {
  85. try {
  86. new DynamicMethod (null,
  87. MethodAttributes.Public | MethodAttributes.Static,
  88. CallingConventions.Standard,
  89. typeof (void),
  90. new Type[] { typeof (string) },
  91. typeof (DynamicMethodTest).Module, true);
  92. Assert.Fail ("#1");
  93. } catch (ArgumentNullException ex) {
  94. Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
  95. Assert.AreEqual ("name", ex.ParamName, "#3");
  96. Assert.IsNull (ex.InnerException, "#4");
  97. }
  98. }
  99. [Test]
  100. public void Constructor6_Name_Null ()
  101. {
  102. try {
  103. new DynamicMethod (null,
  104. MethodAttributes.Public | MethodAttributes.Static,
  105. CallingConventions.Standard,
  106. typeof (void),
  107. new Type[] { typeof (string) },
  108. typeof (DynamicMethodTest), true);
  109. Assert.Fail ("#1");
  110. } catch (ArgumentNullException ex) {
  111. Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
  112. Assert.AreEqual ("name", ex.ParamName, "#3");
  113. Assert.IsNull (ex.InnerException, "#4");
  114. }
  115. }
  116. [Test]
  117. public void OwnerCantBeArray ()
  118. {
  119. TestOwner (typeof (int[]));
  120. }
  121. [Test]
  122. public void OwnerCantBeInterface ()
  123. {
  124. TestOwner (typeof (global::System.Collections.IEnumerable));
  125. }
  126. private void TestOwner (Type owner)
  127. {
  128. try {
  129. new DynamicMethod ("Name", MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard,
  130. typeof(void), new Type[] { }, owner, true);
  131. Assert.Fail (string.Format ("Created dynamic method with owner being {0}.", owner));
  132. } catch (ArgumentException) {
  133. }
  134. }
  135. [Test] // bug #78253
  136. public void DynamicMethodReference ()
  137. {
  138. DynamicMethod hello = new DynamicMethod ("Hello",
  139. typeof (int),
  140. new Type[] { typeof (string) },
  141. typeof (DynamicMethodTest).Module);
  142. Assert.IsNull (hello.DeclaringType, "#1");
  143. DynamicMethod write = new DynamicMethod ("Write",
  144. typeof (int),
  145. new Type[] { typeof (string) },
  146. typeof (DynamicMethodTest));
  147. Assert.IsNull (hello.DeclaringType, "#2");
  148. MethodInfo invokeWrite = write.GetBaseDefinition ();
  149. ILGenerator helloIL = hello.GetILGenerator ();
  150. helloIL.Emit (OpCodes.Ldarg_0);
  151. helloIL.EmitCall (OpCodes.Call, invokeWrite, null);
  152. helloIL.Emit (OpCodes.Ret);
  153. ILGenerator writeIL = write.GetILGenerator ();
  154. writeIL.Emit (OpCodes.Ldc_I4_2);
  155. writeIL.Emit (OpCodes.Ret);
  156. HelloInvoker hi =
  157. (HelloInvoker) hello.CreateDelegate (typeof (HelloInvoker));
  158. int ret = hi ("Hello, World!");
  159. Assert.AreEqual (2, ret, "#3");
  160. object[] invokeArgs = { "Hello, World!" };
  161. object objRet = hello.Invoke (null, invokeArgs);
  162. Assert.AreEqual (2, objRet, "#4");
  163. }
  164. [Test]
  165. public void EmptyMethodBody ()
  166. {
  167. DynamicMethod hello = new DynamicMethod ("Hello",
  168. typeof (int),
  169. new Type[] { typeof (string) },
  170. typeof (DynamicMethodTest).Module);
  171. object[] invokeArgs = { "Hello, World!" };
  172. // no IL generator
  173. try {
  174. hello.Invoke (null, invokeArgs);
  175. Assert.Fail ("#1");
  176. } catch (InvalidOperationException) {
  177. }
  178. // empty method body
  179. hello.GetILGenerator ();
  180. try {
  181. hello.Invoke (null, invokeArgs);
  182. Assert.Fail ("#2");
  183. } catch (InvalidOperationException) {
  184. }
  185. }
  186. private delegate string ReturnString (string msg);
  187. private delegate void DoNothing (string msg);
  188. private static string private_method (string s) {
  189. return s;
  190. }
  191. [Test]
  192. public void SkipVisibility ()
  193. {
  194. DynamicMethod hello = new DynamicMethod ("Hello",
  195. typeof (string),
  196. new Type[] { typeof (string) },
  197. typeof (DynamicMethodTest).Module, true);
  198. ILGenerator helloIL = hello.GetILGenerator ();
  199. helloIL.Emit (OpCodes.Ldarg_0);
  200. helloIL.EmitCall (OpCodes.Call, typeof (DynamicMethodTest).GetMethod ("private_method", BindingFlags.Static|BindingFlags.NonPublic), null);
  201. helloIL.Emit (OpCodes.Ret);
  202. ReturnString del =
  203. (ReturnString) hello.CreateDelegate (typeof (ReturnString));
  204. Assert.AreEqual ("ABCD", del ("ABCD"));
  205. }
  206. [Test]
  207. public void ReturnType_Null ()
  208. {
  209. DynamicMethod hello = new DynamicMethod ("Hello",
  210. null,
  211. new Type[] { typeof (string) },
  212. typeof (DynamicMethodTest).Module, true);
  213. Assert.AreEqual (typeof (void), hello.ReturnType, "#1");
  214. ILGenerator helloIL = hello.GetILGenerator ();
  215. helloIL.Emit (OpCodes.Ret);
  216. DoNothing dn = (DoNothing) hello.CreateDelegate (typeof (DoNothing));
  217. dn ("whatever");
  218. object[] invokeArgs = { "Hello, World!" };
  219. object objRet = hello.Invoke (null, invokeArgs);
  220. Assert.IsNull (objRet, "#2");
  221. }
  222. [Test]
  223. public void Name_Empty ()
  224. {
  225. DynamicMethod hello = new DynamicMethod (string.Empty,
  226. typeof (int),
  227. new Type[] { typeof (string) },
  228. typeof (DynamicMethodTest).Module);
  229. Assert.AreEqual (string.Empty, hello.Name, "#1");
  230. DynamicMethod write = new DynamicMethod ("Write",
  231. typeof (int),
  232. new Type[] { typeof (string) },
  233. typeof (DynamicMethodTest));
  234. MethodInfo invokeWrite = write.GetBaseDefinition ();
  235. ILGenerator helloIL = hello.GetILGenerator ();
  236. helloIL.Emit (OpCodes.Ldarg_0);
  237. helloIL.EmitCall (OpCodes.Call, invokeWrite, null);
  238. helloIL.Emit (OpCodes.Ret);
  239. ILGenerator writeIL = write.GetILGenerator ();
  240. writeIL.Emit (OpCodes.Ldc_I4_2);
  241. writeIL.Emit (OpCodes.Ret);
  242. HelloInvoker hi =
  243. (HelloInvoker) hello.CreateDelegate (typeof (HelloInvoker));
  244. int ret = hi ("Hello, World!");
  245. Assert.AreEqual (2, ret, "#2");
  246. object[] invokeArgs = { "Hello, World!" };
  247. object objRet = hello.Invoke (null, invokeArgs);
  248. Assert.AreEqual (2, objRet, "#3");
  249. }
  250. [Test]
  251. public void Circular_Refs () {
  252. DynamicMethod m1 = new DynamicMethod("f1", typeof(int), new Type[] { typeof (int) },
  253. typeof(object));
  254. DynamicMethod m2 = new DynamicMethod("f2", typeof(int), new Type[] { typeof (int) },
  255. typeof(object));
  256. ILGenerator il1 = m1.GetILGenerator();
  257. ILGenerator il2 = m2.GetILGenerator();
  258. Label l = il1.DefineLabel ();
  259. //il1.EmitWriteLine ("f1");
  260. il1.Emit (OpCodes.Ldarg_0);
  261. il1.Emit (OpCodes.Ldc_I4_0);
  262. il1.Emit (OpCodes.Bne_Un, l);
  263. il1.Emit (OpCodes.Ldarg_0);
  264. il1.Emit (OpCodes.Ret);
  265. il1.MarkLabel (l);
  266. il1.Emit (OpCodes.Ldarg_0);
  267. il1.Emit (OpCodes.Ldc_I4_1);
  268. il1.Emit (OpCodes.Sub);
  269. il1.Emit (OpCodes.Call, m2);
  270. il1.Emit (OpCodes.Ret);
  271. //il2.EmitWriteLine("f2");
  272. il2.Emit(OpCodes.Ldarg_0);
  273. il2.Emit(OpCodes.Call, m1);
  274. il2.Emit(OpCodes.Ret);
  275. m1.Invoke(null, new object[] { 5 });
  276. }
  277. // Disabl known warning, the Field is never used directly from C#
  278. #pragma warning disable 414
  279. class Host {
  280. static string Field = "foo";
  281. }
  282. #pragma warning restore 414
  283. [Test]
  284. [Category ("NotDotNet")] // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=297416
  285. public void TestOwnerMemberAccess ()
  286. {
  287. DynamicMethod method = new DynamicMethod ("GetField",
  288. typeof (string), new Type [0], typeof (Host));
  289. ILGenerator il = method.GetILGenerator ();
  290. il.Emit (OpCodes.Ldsfld, typeof (Host).GetField (
  291. "Field", BindingFlags.Static | BindingFlags.NonPublic));
  292. il.Emit (OpCodes.Ret);
  293. string ret = (string) method.Invoke (null, new object [] {});
  294. Assert.AreEqual ("foo", ret, "#1");
  295. }
  296. [Test]
  297. public void AnonHosted ()
  298. {
  299. DynamicMethod hello = new DynamicMethod ("Hello",
  300. typeof (int),
  301. new Type[] { typeof (string) });
  302. ILGenerator helloIL = hello.GetILGenerator ();
  303. helloIL.Emit (OpCodes.Ldc_I4_2);
  304. helloIL.Emit (OpCodes.Ret);
  305. HelloInvoker hi =
  306. (HelloInvoker) hello.CreateDelegate (typeof (HelloInvoker));
  307. int ret = hi ("Hello, World!");
  308. Assert.AreEqual (2, ret);
  309. object[] invokeArgs = { "Hello, World!" };
  310. object objRet = hello.Invoke (null, invokeArgs);
  311. Assert.AreEqual (2, objRet);
  312. }
  313. public delegate int IntInvoker();
  314. public class Foo<T> {
  315. public virtual int Test () { return 99; }
  316. }
  317. [Test]
  318. public void ConstrainedPrexixDoesntCrash () //bug #529238
  319. {
  320. Type foo = typeof (Foo<int>);
  321. DynamicMethod dm = new DynamicMethod ("Hello", typeof (int), null);
  322. ILGenerator ilgen = dm.GetILGenerator ();
  323. ilgen.DeclareLocal (foo);
  324. ilgen.Emit (OpCodes.Newobj, foo.GetConstructor (new Type [0]));
  325. ilgen.Emit (OpCodes.Stloc_0);
  326. ilgen.Emit (OpCodes.Ldloca_S, 0);
  327. ilgen.Emit (OpCodes.Constrained, foo);
  328. ilgen.Emit (OpCodes.Callvirt, foo.GetMethod ("Test"));
  329. ilgen.Emit (OpCodes.Ret);
  330. IntInvoker hi = (IntInvoker) dm.CreateDelegate (typeof (IntInvoker));
  331. Assert.AreEqual (99, hi (), "#1");
  332. }
  333. // #575955
  334. [Test]
  335. public void Module_GetMethod () {
  336. AssemblyName assemblyName = new AssemblyName ();
  337. assemblyName.Name = "foo";
  338. AssemblyBuilder assembly =
  339. AppDomain.CurrentDomain.DefineDynamicAssembly (
  340. assemblyName, AssemblyBuilderAccess.RunAndSave);
  341. ModuleBuilder module = assembly.DefineDynamicModule ("foo.dll");
  342. var d = new DynamicMethod ("foo", typeof (int), new Type [] { typeof (int[,]) }, module);
  343. var ig = d.GetILGenerator ();
  344. ig.Emit (OpCodes.Ldarg_0);
  345. ig.Emit (OpCodes.Ldc_I4, 1);
  346. ig.Emit (OpCodes.Ldc_I4, 1);
  347. ig.Emit (OpCodes.Call, module.GetArrayMethod (typeof (int[,]), "Get", CallingConventions.Standard, typeof (int), new Type [] { typeof (int), typeof (int) }));
  348. ig.Emit (OpCodes.Ret);
  349. var del = (Func<int[,], int>)d.CreateDelegate (typeof (Func<int[,], int>));
  350. int[,] arr = new int [10, 10];
  351. arr [1, 1] = 5;
  352. Assert.AreEqual (5, del (arr));
  353. }
  354. [Test]
  355. [Category ("NotWorking")]
  356. public void InvalidUnicodeName ()
  357. {
  358. var name = new StringBuilder ().Append ('\udf45').Append ('\ud808');
  359. var method = new DynamicMethod (name.ToString (), typeof (bool), new Type [0]);
  360. var il = method.GetILGenerator ();
  361. il.Emit (OpCodes.Ldc_I4_1);
  362. il.Emit (OpCodes.Ret);
  363. var function = (Func<bool>) method.CreateDelegate (typeof (Func<bool>));
  364. Assert.IsTrue (function ());
  365. }
  366. [Test]
  367. [ExpectedException (typeof (InvalidOperationException))]
  368. public void GetMethodBody ()
  369. {
  370. var method = new DynamicMethod ("method", typeof (object), new Type [] { typeof (object) });
  371. var il = method.GetILGenerator ();
  372. il.Emit (OpCodes.Ldarg_0);
  373. il.Emit (OpCodes.Ret);
  374. var f = (Func<object, object>) method.CreateDelegate (typeof (Func<object, object>));
  375. f.Method.GetMethodBody ();
  376. }
  377. public delegate object RetObj();
  378. [Test] //#640702
  379. public void GetCurrentMethodWorksWithDynamicMethods ()
  380. {
  381. DynamicMethod dm = new DynamicMethod("Foo", typeof(object), null);
  382. ILGenerator ilgen = dm.GetILGenerator();
  383. ilgen.Emit(OpCodes.Call, typeof(MethodBase).GetMethod("GetCurrentMethod"));
  384. ilgen.Emit(OpCodes.Ret);
  385. RetObj del = (RetObj)dm.CreateDelegate(typeof(RetObj));
  386. MethodInfo res = (MethodInfo)del();
  387. Assert.AreEqual (dm.Name, res.Name, "#1");
  388. }
  389. [StructLayout (LayoutKind.Explicit)]
  390. struct SizeOfTarget {
  391. [FieldOffset (0)] public int X;
  392. [FieldOffset (4)] public int Y;
  393. }
  394. [Test]
  395. public void SizeOf ()
  396. {
  397. var method = new DynamicMethod ("", typeof (int), Type.EmptyTypes);
  398. var il = method.GetILGenerator ();
  399. il.Emit (OpCodes.Sizeof, typeof (SizeOfTarget));
  400. il.Emit (OpCodes.Ret);
  401. var func = (Func<int>) method.CreateDelegate (typeof (Func<int>));
  402. var point_size = func ();
  403. Assert.AreEqual (8, point_size);
  404. }
  405. class TypedRefTarget {
  406. public string Name;
  407. }
  408. class ExceptionHandling_Test_Support
  409. {
  410. public static Exception Caught;
  411. public static string CaughtStackTrace;
  412. public static void ThrowMe ()
  413. {
  414. Caught = null;
  415. CaughtStackTrace = null;
  416. throw new Exception("test");
  417. }
  418. public static void Handler (Exception e)
  419. {
  420. Caught = e;
  421. CaughtStackTrace = e.StackTrace.ToString ();
  422. }
  423. }
  424. [Test]
  425. public void ExceptionHandling ()
  426. {
  427. var method = new DynamicMethod ("", typeof(void), new[] { typeof(int) }, typeof (DynamicMethodTest));
  428. var ig = method.GetILGenerator ();
  429. ig.BeginExceptionBlock();
  430. ig.Emit(OpCodes.Call, typeof(ExceptionHandling_Test_Support).GetMethod("ThrowMe"));
  431. ig.BeginCatchBlock(typeof(Exception));
  432. ig.Emit(OpCodes.Call, typeof(ExceptionHandling_Test_Support).GetMethod("Handler"));
  433. ig.EndExceptionBlock();
  434. ig.Emit(OpCodes.Ret);
  435. var invoke = (Action<int>) method.CreateDelegate (typeof(Action<int>));
  436. invoke (456324);
  437. Assert.IsNotNull (ExceptionHandling_Test_Support.Caught, "#1");
  438. Assert.AreEqual (2, ExceptionHandling_Test_Support.CaughtStackTrace.Split (new[] { Environment.NewLine }, StringSplitOptions.None).Length, "#2");
  439. var st = new StackTrace (ExceptionHandling_Test_Support.Caught, 0, true);
  440. // Caught stack trace when dynamic method is gone
  441. Assert.AreEqual (ExceptionHandling_Test_Support.CaughtStackTrace, st.ToString (), "#3");
  442. // Catch handler stack trace inside dynamic method match
  443. Assert.AreEqual (ExceptionHandling_Test_Support.Caught.StackTrace, st.ToString (), "#4");
  444. }
  445. class ExceptionHandlingWithExceptionDispatchInfo_Test_Support
  446. {
  447. public static Exception Caught;
  448. public static string CaughtStackTrace;
  449. public static void ThrowMe ()
  450. {
  451. Caught = null;
  452. CaughtStackTrace = null;
  453. Exception e;
  454. try {
  455. throw new Exception("test");
  456. } catch (Exception e2) {
  457. e = e2;
  458. }
  459. var edi = ExceptionDispatchInfo.Capture(e);
  460. edi.Throw();
  461. }
  462. public static void Handler (Exception e)
  463. {
  464. var split = e.StackTrace.Split (new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
  465. Assert.AreEqual (5, split.Length, "#1");
  466. Assert.IsTrue (split [1].Contains ("---"), "#2");
  467. }
  468. }
  469. [Test]
  470. public void ExceptionHandlingWithExceptionDispatchInfo ()
  471. {
  472. var method = new DynamicMethod ("", typeof(void), new[] { typeof(int) }, typeof (DynamicMethodTest));
  473. var ig = method.GetILGenerator ();
  474. ig.BeginExceptionBlock();
  475. ig.Emit(OpCodes.Call, typeof(ExceptionHandlingWithExceptionDispatchInfo_Test_Support).GetMethod("ThrowMe"));
  476. ig.BeginCatchBlock(typeof(Exception));
  477. ig.Emit(OpCodes.Call, typeof(ExceptionHandlingWithExceptionDispatchInfo_Test_Support).GetMethod("Handler"));
  478. ig.EndExceptionBlock();
  479. ig.Emit(OpCodes.Ret);
  480. var invoke = (Action<int>) method.CreateDelegate (typeof(Action<int>));
  481. invoke (444);
  482. }
  483. #if !MONODROID
  484. // RUNTIME: crash
  485. [Test]
  486. public void TypedRef ()
  487. {
  488. var method = new DynamicMethod ("", typeof (TypedRefTarget), new [] {typeof (TypedRefTarget)}, true);
  489. var il = method.GetILGenerator ();
  490. var tr = il.DeclareLocal (typeof (TypedReference));
  491. il.Emit (OpCodes.Ldarga, 0);
  492. il.Emit (OpCodes.Mkrefany, typeof (TypedRefTarget));
  493. il.Emit (OpCodes.Stloc, tr);
  494. il.Emit (OpCodes.Ldloc, tr);
  495. il.Emit (OpCodes.Call, GetType ().GetMethod ("AssertTypedRef", BindingFlags.NonPublic | BindingFlags.Static));
  496. il.Emit (OpCodes.Ldloc, tr);
  497. il.Emit (OpCodes.Refanyval, typeof (TypedRefTarget));
  498. il.Emit (OpCodes.Ldobj, typeof (TypedRefTarget));
  499. il.Emit (OpCodes.Ret);
  500. var f = (Func<TypedRefTarget, TypedRefTarget>) method.CreateDelegate (typeof (Func<TypedRefTarget, TypedRefTarget>));
  501. var target = new TypedRefTarget { Name = "Foo" };
  502. var rt = f (target);
  503. Assert.AreEqual (target, rt);
  504. }
  505. private static void AssertTypedRef (TypedReference tr)
  506. {
  507. Assert.AreEqual (typeof (TypedRefTarget), TypedReference.GetTargetType (tr));
  508. }
  509. #endif
  510. }
  511. }