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