Merge pull request #587 from madewokherd/gdipdllmap
[mono.git] / mcs / class / corlib / Test / System / DelegateTest.cs
1 // DelegateTest.cs - NUnit Test Cases for the System.Delegate class
2 //
3 // (C) Ximian, Inc.  http://www.ximian.com
4 //
5
6 using System;
7 using System.Reflection;
8 #if !MONOTOUCH
9 using System.Reflection.Emit;
10 #endif
11 using System.Threading;
12
13 using NUnit.Framework;
14
15 namespace MonoTests.System
16 {
17         [TestFixture]
18         public class DelegateTest
19         {
20 #if NET_2_0
21                 
22                 public class GenericClass<T> {
23                         public void Method<K> (T t, K k) {}
24                 }
25
26                 public delegate void SimpleDelegate(int a, double b);
27
28
29                 [Test] //See bug #372406
30 #if MONOTOUCH
31                 [Category ("NotWorking")] // #10539
32 #endif
33                 public void CreateDelegate1_Method_Private_Instance ()
34                 {
35                         C c = new C ();
36                         MethodInfo mi = typeof (C).GetMethod ("PrivateInstance", BindingFlags.NonPublic | BindingFlags.Instance);
37                         Delegate dg = Delegate.CreateDelegate (typeof (D), mi);
38                         Assert.AreSame (mi, dg.Method, "#1");
39                         Assert.IsNull (dg.Target, "#2");
40                         D d = (D) dg;
41                         d (c);
42                 }
43
44                 [Test] //Fixes a regression #377324
45                 public void GetMethodFromGenericClass ()
46                 {
47                         GenericClass<int> gclass = new GenericClass<int>();
48                         SimpleDelegate d = new SimpleDelegate (gclass.Method<double>);
49                         MethodInfo method = d.Method;
50                         MethodInfo target = typeof (GenericClass<int>).GetMethod ("Method").MakeGenericMethod(typeof(double));
51                         Assert.IsNotNull (method, "#1");
52                         Assert.AreEqual (target, method, "#2");
53                 }
54 #endif
55
56                 [Test] // CreateDelegate (Type, MethodInfo)
57                 public void CreateDelegate1_Method_Static ()
58                 {
59                         C c = new C ();
60                         MethodInfo mi = typeof (C).GetMethod ("S");
61                         Delegate dg = Delegate.CreateDelegate (typeof (D), mi);
62                         Assert.AreSame (mi, dg.Method, "#1");
63                         Assert.IsNull (dg.Target, "#2");
64                         D d = (D) dg;
65                         d (c);
66                 }
67
68                 [Test] // CreateDelegate (Type, MethodInfo)
69 #if MONOTOUCH
70                 [Category ("NotWorking")] // #14163
71 #endif
72                 public void CreateDelegate1_Method_Instance ()
73                 {
74                         C c = new C ();
75                         MethodInfo mi = typeof (C).GetMethod ("M");
76 #if NET_2_0
77                         Delegate dg = Delegate.CreateDelegate (typeof (D), mi);
78                         Assert.AreSame (mi, dg.Method, "#1");
79                         Assert.IsNull (dg.Target, "#2");
80                         D d = (D) dg;
81                         d (c);
82 #else
83                         try {
84                                 Delegate.CreateDelegate (typeof (D), mi);
85                                 Assert.Fail ("#1");
86                         } catch (ArgumentException ex) {
87                                 // Method must be a static method
88                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
89                                 Assert.IsNull (ex.InnerException, "#3");
90                                 Assert.IsNotNull (ex.Message, "#4");
91                                 Assert.IsNotNull (ex.ParamName, "#5");
92                                 Assert.AreEqual ("method", ex.ParamName, "#6");
93                         }
94 #endif
95                 }
96
97                 [Test] // CreateDelegate (Type, MethodInfo)
98                 public void CreateDelegate1_Method_Null ()
99                 {
100                         try {
101                                 Delegate.CreateDelegate (typeof (D), (MethodInfo) null);
102                                 Assert.Fail ("#1");
103                         } catch (ArgumentNullException ex) {
104                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
105                                 Assert.IsNull (ex.InnerException, "#3");
106                                 Assert.IsNotNull (ex.Message, "#4");
107                                 Assert.IsNotNull (ex.ParamName, "#5");
108                                 Assert.AreEqual ("method", ex.ParamName, "#6");
109                         }
110                 }
111
112                 [Test] // CreateDelegate (Type, MethodInfo)
113                 public void CreateDelegate1_Type_Null ()
114                 {
115                         MethodInfo mi = typeof (C).GetMethod ("S");
116                         try {
117                                 Delegate.CreateDelegate ((Type) null, mi);
118                                 Assert.Fail ("#1");
119                         } catch (ArgumentNullException ex) {
120                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
121                                 Assert.IsNull (ex.InnerException, "#3");
122                                 Assert.IsNotNull (ex.Message, "#4");
123                                 Assert.IsNotNull (ex.ParamName, "#5");
124                                 Assert.AreEqual ("type", ex.ParamName, "#6");
125                         }
126                 }
127
128                 [Test] // CreateDelegate (Type, Object, String)
129                 public void CreateDelegate2 ()
130                 {
131                         E e;
132
133                         e = (E) Delegate.CreateDelegate (typeof (E), new B (), "Execute");
134                         Assert.IsNotNull (e, "#A1");
135                         Assert.AreEqual (4, e (new C ()), "#A2");
136
137                         e = (E) Delegate.CreateDelegate (typeof (E), new C (), "Execute");
138                         Assert.IsNotNull (e, "#B1");
139                         Assert.AreEqual (4, e (new C ()), "#D2");
140
141                         e = (E) Delegate.CreateDelegate (typeof (E), new C (), "DoExecute");
142                         Assert.IsNotNull (e, "#C1");
143                         Assert.AreEqual (102, e (new C ()), "#C2");
144                 }
145
146                 [Test] // CreateDelegate (Type, Object, String)
147                 public void CreateDelegate2_Method_ArgumentsMismatch ()
148                 {
149                         try {
150                                 Delegate.CreateDelegate (typeof (E), new B (),
151                                         "StartExecute");
152                                 Assert.Fail ("#1");
153                         } catch (ArgumentException ex) {
154                                 // Error binding to target method
155                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
156                                 Assert.IsNull (ex.InnerException, "#3");
157                                 Assert.IsNotNull (ex.Message, "#4");
158                                 Assert.IsNull (ex.ParamName, "#5");
159                         }
160                 }
161
162                 [Test] // CreateDelegate (Type, Object, String)
163                 public void CreateDelegate2_Method_CaseMismatch ()
164                 {
165                         try {
166                                 Delegate.CreateDelegate (typeof (E), new B (), "ExecutE");
167                                 Assert.Fail ("#1");
168                         } catch (ArgumentException ex) {
169                                 // Error binding to target method
170                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
171                                 Assert.IsNull (ex.InnerException, "#3");
172                                 Assert.IsNotNull (ex.Message, "#4");
173                                 Assert.IsNull (ex.ParamName, "#5");
174                         }
175                 }
176
177                 [Test] // CreateDelegate (Type, Object, String)
178                 public void CreateDelegate2_Method_DoesNotExist ()
179                 {
180                         try {
181                                 Delegate.CreateDelegate (typeof (E), new B (),
182                                         "DoesNotExist");
183                                 Assert.Fail ("#1");
184                         } catch (ArgumentException ex) {
185                                 // Error binding to target method
186                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
187                                 Assert.IsNull (ex.InnerException, "#3");
188                                 Assert.IsNotNull (ex.Message, "#4");
189                                 Assert.IsNull (ex.ParamName, "#5");
190                         }
191                 }
192
193                 [Test] // CreateDelegate (Type, Object, String)
194                 public void CreateDelegate2_Method_Null ()
195                 {
196                         C c = new C ();
197                         try {
198                                 Delegate.CreateDelegate (typeof (D), c, (string) null);
199                                 Assert.Fail ("#1");
200                         } catch (ArgumentNullException ex) {
201                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
202                                 Assert.IsNull (ex.InnerException, "#3");
203                                 Assert.IsNotNull (ex.Message, "#4");
204                                 Assert.IsNotNull (ex.ParamName, "#5");
205                                 Assert.AreEqual ("method", ex.ParamName, "#6");
206                         }
207                 }
208
209                 [Test] // CreateDelegate (Type, Object, String)
210                 public void CreateDelegate2_Method_ReturnTypeMismatch ()
211                 {
212                         try {
213                                 Delegate.CreateDelegate (typeof (E), new B (),
214                                         "DoExecute");
215                                 Assert.Fail ("#1");
216                         } catch (ArgumentException ex) {
217                                 // Error binding to target method
218                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
219                                 Assert.IsNull (ex.InnerException, "#3");
220                                 Assert.IsNotNull (ex.Message, "#4");
221                                 Assert.IsNull (ex.ParamName, "#5");
222                         }
223                 }
224
225                 [Test] // CreateDelegate (Type, Object, String)
226                 public void CreateDelegate2_Method_Static ()
227                 {
228                         try {
229                                 Delegate.CreateDelegate (typeof (E), new B (), "Run");
230                                 Assert.Fail ("#1");
231                         } catch (ArgumentException ex) {
232                                 // Error binding to target method
233                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
234                                 Assert.IsNull (ex.InnerException, "#3");
235                                 Assert.IsNotNull (ex.Message, "#4");
236                                 Assert.IsNull (ex.ParamName, "#5");
237                         }
238                 }
239
240                 [Test] // CreateDelegate (Type, Object, String)
241                 public void CreateDelegate2_Target_Null ()
242                 {
243                         try {
244                                 Delegate.CreateDelegate (typeof (D),null, "N");
245                                 Assert.Fail ("#1");
246                         } catch (ArgumentNullException ex) {
247                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
248                                 Assert.IsNull (ex.InnerException, "#3");
249                                 Assert.IsNotNull (ex.Message, "#4");
250                                 Assert.IsNotNull (ex.ParamName, "#5");
251                                 Assert.AreEqual ("target", ex.ParamName, "#6");
252                         }
253                 }
254
255                 [Test] // CreateDelegate (Type, Object, String)
256                 public void CreateDelegate2_Type_Null ()
257                 {
258                         C c = new C ();
259                         try {
260                                 Delegate.CreateDelegate ((Type) null, c, "N");
261                                 Assert.Fail ("#1");
262                         } catch (ArgumentNullException ex) {
263                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
264                                 Assert.IsNull (ex.InnerException, "#3");
265                                 Assert.IsNotNull (ex.Message, "#4");
266                                 Assert.IsNotNull (ex.ParamName, "#5");
267                                 Assert.AreEqual ("type", ex.ParamName, "#6");
268                         }
269                 }
270
271                 [Test] // CreateDelegate (Type, Type, String)
272                 public void CreateDelegate3 ()
273                 {
274                         E e;
275
276                         // matching static method
277                         e = (E) Delegate.CreateDelegate (typeof (E), typeof (B), "Run");
278                         Assert.IsNotNull (e, "#A1");
279                         Assert.AreEqual (5, e (new C ()), "#A2");
280
281                         // matching static method
282                         e = (E) Delegate.CreateDelegate (typeof (E), typeof (C), "Run");
283                         Assert.IsNotNull (e, "#B1");
284                         Assert.AreEqual (5, e (new C ()), "#B2");
285
286                         // matching static method
287                         e = (E) Delegate.CreateDelegate (typeof (E), typeof (C), "DoRun");
288                         Assert.IsNotNull (e, "#C1");
289                         Assert.AreEqual (107, e (new C ()), "#C2");
290                 }
291
292                 [Test] // CreateDelegate (Type, Type, String)
293                 public void CreateDelegate3_Method_ArgumentsMismatch ()
294                 {
295                         try {
296                                 Delegate.CreateDelegate (typeof (E), typeof (B),
297                                         "StartRun");
298                                 Assert.Fail ("#1");
299                         } catch (ArgumentException ex) {
300                                 // Error binding to target method
301                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
302                                 Assert.IsNull (ex.InnerException, "#3");
303                                 Assert.IsNotNull (ex.Message, "#4");
304                                 Assert.IsNull (ex.ParamName, "#5");
305                         }
306                 }
307
308                 [Test] // CreateDelegate (Type, Type, String)
309                 public void CreateDelegate3_Method_CaseMismatch ()
310                 {
311                         try {
312                                 Delegate.CreateDelegate (typeof (E), typeof (B), "RuN");
313                                 Assert.Fail ("#1");
314                         } catch (ArgumentException ex) {
315                                 // Error binding to target method
316                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
317                                 Assert.IsNull (ex.InnerException, "#3");
318                                 Assert.IsNotNull (ex.Message, "#4");
319                                 Assert.IsNull (ex.ParamName, "#5");
320                         }
321                 }
322
323                 [Test] // CreateDelegate (Type, Type, String)
324                 public void CreateDelegate3_Method_DoesNotExist ()
325                 {
326                         try {
327                                 Delegate.CreateDelegate (typeof (E), typeof (B),
328                                         "DoesNotExist");
329                                 Assert.Fail ("#1");
330                         } catch (ArgumentException ex) {
331                                 // Error binding to target method
332                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
333                                 Assert.IsNull (ex.InnerException, "#3");
334                                 Assert.IsNotNull (ex.Message, "#4");
335                                 Assert.IsNull (ex.ParamName, "#5");
336                         }
337                 }
338
339                 [Test] // CreateDelegate (Type, Type, String)
340                 public void CreateDelegate3_Method_Instance ()
341                 {
342                         try {
343                                 Delegate.CreateDelegate (typeof (E), typeof (B), "Execute");
344                                 Assert.Fail ("#1");
345                         } catch (ArgumentException ex) {
346                                 // Error binding to target method
347                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
348                                 Assert.IsNull (ex.InnerException, "#3");
349                                 Assert.IsNotNull (ex.Message, "#4");
350                                 Assert.IsNull (ex.ParamName, "#5");
351                         }
352                 }
353
354                 [Test] // CreateDelegate (Type, Type, String)
355                 public void CreateDelegate3_Method_Null ()
356                 {
357                         try {
358                                 Delegate.CreateDelegate (typeof (D), typeof (C), (string) null);
359                                 Assert.Fail ("#1");
360                         } catch (ArgumentNullException ex) {
361                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
362                                 Assert.IsNull (ex.InnerException, "#3");
363                                 Assert.IsNotNull (ex.Message, "#4");
364                                 Assert.IsNotNull (ex.ParamName, "#5");
365                                 Assert.AreEqual ("method", ex.ParamName, "#6");
366                         }
367                 }
368
369                 [Test] // CreateDelegate (Type, Type, String)
370                 public void CreateDelegate3_Method_ReturnTypeMismatch ()
371                 {
372                         try {
373                                 Delegate.CreateDelegate (typeof (E), typeof (B),
374                                         "DoRun");
375                                 Assert.Fail ("#1");
376                         } catch (ArgumentException ex) {
377                                 // Error binding to target method
378                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
379                                 Assert.IsNull (ex.InnerException, "#3");
380                                 Assert.IsNotNull (ex.Message, "#4");
381                                 Assert.IsNull (ex.ParamName, "#5");
382                         }
383                 }
384
385                 [Test] // CreateDelegate (Type, Type, String)
386                 public void CreateDelegate3_Target_Null ()
387                 {
388                         try {
389                                 Delegate.CreateDelegate (typeof (D), (Type) null, "S");
390                                 Assert.Fail ("#1");
391                         } catch (ArgumentNullException ex) {
392                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
393                                 Assert.IsNull (ex.InnerException, "#3");
394                                 Assert.IsNotNull (ex.Message, "#4");
395                                 Assert.IsNotNull (ex.ParamName, "#5");
396                                 Assert.AreEqual ("target", ex.ParamName, "#6");
397                         }
398                 }
399
400                 [Test] // CreateDelegate (Type, Type, String)
401                 public void CreateDelegate3_Type_Null ()
402                 {
403                         try {
404                                 Delegate.CreateDelegate ((Type) null, typeof (C), "S");
405                                 Assert.Fail ("#1");
406                         } catch (ArgumentNullException ex) {
407                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
408                                 Assert.IsNull (ex.InnerException, "#3");
409                                 Assert.IsNotNull (ex.Message, "#4");
410                                 Assert.IsNotNull (ex.ParamName, "#5");
411                                 Assert.AreEqual ("type", ex.ParamName, "#6");
412                         }
413                 }
414
415                 [Test] // CreateDelegate (Type, Object, String, Boolean)
416                 public void CreateDelegate4 ()
417                 {
418                         E e;
419
420                         B b = new B ();
421
422                         // instance method, exact case, ignore case
423                         e = (E) Delegate.CreateDelegate (typeof (E), b, "Execute", true);
424                         Assert.IsNotNull (e, "#A1");
425                         Assert.AreEqual (4, e (new C ()), "#A2");
426
427                         // instance method, exact case, do not ignore case
428                         e = (E) Delegate.CreateDelegate (typeof (E), b, "Execute", false);
429                         Assert.IsNotNull (e, "#B1");
430                         Assert.AreEqual (4, e (new C ()), "#B2");
431
432                         // instance method, case mismatch, ignore case
433                         e = (E) Delegate.CreateDelegate (typeof (E), b, "ExecutE", true);
434                         Assert.IsNotNull (e, "#C1");
435                         Assert.AreEqual (4, e (new C ()), "#C2");
436
437                         C c = new C ();
438
439                         // instance method, exact case, ignore case
440                         e = (E) Delegate.CreateDelegate (typeof (E), c, "Execute", true);
441                         Assert.IsNotNull (e, "#D1");
442                         Assert.AreEqual (4, e (new C ()), "#D2");
443
444                         // instance method, exact case, ignore case
445                         e = (E) Delegate.CreateDelegate (typeof (E), c, "DoExecute", true);
446                         Assert.IsNotNull (e, "#E1");
447                         Assert.AreEqual (102, e (new C ()), "#E2");
448
449                         // instance method, exact case, do not ignore case
450                         e = (E) Delegate.CreateDelegate (typeof (E), c, "Execute", false);
451                         Assert.IsNotNull (e, "#F1");
452                         Assert.AreEqual (4, e (new C ()), "#F2");
453
454                         // instance method, case mismatch, ignore case
455                         e = (E) Delegate.CreateDelegate (typeof (E), c, "ExecutE", true);
456                         Assert.IsNotNull (e, "#G1");
457                         Assert.AreEqual (4, e (new C ()), "#G2");
458                 }
459
460                 [Test] // CreateDelegate (Type, Object, String, Boolean)
461                 public void CreateDelegate4_Method_ArgumentsMismatch ()
462                 {
463                         try {
464                                 Delegate.CreateDelegate (typeof (E), new B (),
465                                         "StartExecute", false);
466                                 Assert.Fail ("#1");
467                         } catch (ArgumentException ex) {
468                                 // Error binding to target method
469                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
470                                 Assert.IsNull (ex.InnerException, "#3");
471                                 Assert.IsNotNull (ex.Message, "#4");
472                                 Assert.IsNull (ex.ParamName, "#5");
473                         }
474                 }
475
476                 [Test] // CreateDelegate (Type, Object, String, Boolean)
477                 public void CreateDelegate4_Method_CaseMismatch ()
478                 {
479                         // instance method, case mismatch, do not igore case
480                         try {
481                                 Delegate.CreateDelegate (typeof (E), new B (),
482                                         "ExecutE", false);
483                                 Assert.Fail ("#1");
484                         } catch (ArgumentException ex) {
485                                 // Error binding to target method
486                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
487                                 Assert.IsNull (ex.InnerException, "#3");
488                                 Assert.IsNotNull (ex.Message, "#4");
489                                 Assert.IsNull (ex.ParamName, "#5");
490                         }
491                 }
492
493                 [Test] // CreateDelegate (Type, Object, String, Boolean)
494                 public void CreateDelegate4_Method_DoesNotExist ()
495                 {
496                         try {
497                                 Delegate.CreateDelegate (typeof (E), new B (),
498                                         "DoesNotExist", false);
499                                 Assert.Fail ("#1");
500                         } catch (ArgumentException ex) {
501                                 // Error binding to target method
502                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
503                                 Assert.IsNull (ex.InnerException, "#3");
504                                 Assert.IsNotNull (ex.Message, "#4");
505                                 Assert.IsNull (ex.ParamName, "#5");
506                         }
507                 }
508
509                 [Test] // CreateDelegate (Type, Object, String, Boolean)
510                 public void CreateDelegate4_Method_Null ()
511                 {
512                         try {
513                                 Delegate.CreateDelegate (typeof (D), new C (),
514                                         (string) null, true);
515                                 Assert.Fail ("#1");
516                         } catch (ArgumentNullException ex) {
517                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
518                                 Assert.IsNull (ex.InnerException, "#3");
519                                 Assert.IsNotNull (ex.Message, "#4");
520                                 Assert.IsNotNull (ex.ParamName, "#5");
521                                 Assert.AreEqual ("method", ex.ParamName, "#6");
522                         }
523                 }
524
525                 [Test] // CreateDelegate (Type, Object, String, Boolean)
526                 public void CreateDelegate4_Method_ReturnTypeMismatch ()
527                 {
528                         try {
529                                 Delegate.CreateDelegate (typeof (E), new B (),
530                                         "DoExecute", false);
531                                 Assert.Fail ("#1");
532                         } catch (ArgumentException ex) {
533                                 // Error binding to target method
534                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
535                                 Assert.IsNull (ex.InnerException, "#3");
536                                 Assert.IsNotNull (ex.Message, "#4");
537                                 Assert.IsNull (ex.ParamName, "#5");
538                         }
539                 }
540
541                 [Test] // CreateDelegate (Type, Object, String, Boolean)
542                 public void CreateDelegate4_Method_Static ()
543                 {
544                         try {
545                                 Delegate.CreateDelegate (typeof (E), new B (), "Run", true);
546                                 Assert.Fail ("#1");
547                         } catch (ArgumentException ex) {
548                                 // Error binding to target method
549                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
550                                 Assert.IsNull (ex.InnerException, "#3");
551                                 Assert.IsNotNull (ex.Message, "#4");
552                                 Assert.IsNull (ex.ParamName, "#5");
553                         }
554                 }
555
556                 [Test] // CreateDelegate (Type, Object, String, Boolean)
557                 public void CreateDelegate4_Target_Null ()
558                 {
559                         try {
560                                 Delegate.CreateDelegate (typeof (D), null, "N", true);
561                                 Assert.Fail ("#1");
562                         } catch (ArgumentNullException ex) {
563                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
564                                 Assert.IsNull (ex.InnerException, "#3");
565                                 Assert.IsNotNull (ex.Message, "#4");
566                                 Assert.IsNotNull (ex.ParamName, "#5");
567                                 Assert.AreEqual ("target", ex.ParamName, "#6");
568                         }
569                 }
570
571                 [Test] // CreateDelegate (Type, Object, String, Boolean)
572                 public void CreateDelegate4_Type_Null ()
573                 {
574                         C c = new C ();
575                         try {
576                                 Delegate.CreateDelegate ((Type) null, c, "N", true);
577                                 Assert.Fail ("#1");
578                         } catch (ArgumentNullException ex) {
579                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
580                                 Assert.IsNull (ex.InnerException, "#3");
581                                 Assert.IsNotNull (ex.Message, "#4");
582                                 Assert.IsNotNull (ex.ParamName, "#5");
583                                 Assert.AreEqual ("type", ex.ParamName, "#6");
584                         }
585                 }
586
587 #if NET_2_0
588                 [Test] // CreateDelegate (Type, Object, String, Boolean, Boolean)
589                 public void CreateDelegate9 ()
590                 {
591                         E e;
592
593                         // do not ignore case, do not throw bind failure
594                         e = (E) Delegate.CreateDelegate (typeof (E), new B (),
595                                 "Execute", false, false);
596                         Assert.IsNotNull (e, "#A1");
597                         Assert.AreEqual (4, e (new C ()), "#A2");
598
599                         // do not ignore case, throw bind failure
600                         e = (E) Delegate.CreateDelegate (typeof (E), new B (),
601                                 "Execute", false, true);
602                         Assert.IsNotNull (e, "#B1");
603                         Assert.AreEqual (4, e (new C ()), "#B2");
604
605                         // ignore case, do not throw bind failure
606                         e = (E) Delegate.CreateDelegate (typeof (E), new B (),
607                                 "Execute", true, false);
608                         Assert.IsNotNull (e, "#C1");
609                         Assert.AreEqual (4, e (new C ()), "#C2");
610
611                         // ignore case, throw bind failure
612                         e = (E) Delegate.CreateDelegate (typeof (E), new B (),
613                                 "Execute", true, true);
614                         Assert.IsNotNull (e, "#D1");
615                         Assert.AreEqual (4, e (new C ()), "#D2");
616
617                         // do not ignore case, do not throw bind failure
618                         e = (E) Delegate.CreateDelegate (typeof (E), new C (),
619                                 "Execute", false, false);
620                         Assert.IsNotNull (e, "#E1");
621                         Assert.AreEqual (4, e (new C ()), "#E2");
622
623                         // do not ignore case, throw bind failure
624                         e = (E) Delegate.CreateDelegate (typeof (E), new C (),
625                                 "Execute", false, true);
626                         Assert.IsNotNull (e, "#F1");
627                         Assert.AreEqual (4, e (new C ()), "#F2");
628
629                         // ignore case, do not throw bind failure
630                         e = (E) Delegate.CreateDelegate (typeof (E), new C (),
631                                 "Execute", true, false);
632                         Assert.IsNotNull (e, "#G1");
633                         Assert.AreEqual (4, e (new C ()), "#G2");
634
635                         // ignore case, throw bind failure
636                         e = (E) Delegate.CreateDelegate (typeof (E), new C (),
637                                 "Execute", true, true);
638                         Assert.IsNotNull (e, "#H1");
639                         Assert.AreEqual (4, e (new C ()), "#H2");
640
641                         // do not ignore case, do not throw bind failure
642                         e = (E) Delegate.CreateDelegate (typeof (E), new C (),
643                                 "DoExecute", false, false);
644                         Assert.IsNotNull (e, "#I1");
645                         Assert.AreEqual (102, e (new C ()), "#I2");
646
647                         // do not ignore case, throw bind failure
648                         e = (E) Delegate.CreateDelegate (typeof (E), new C (),
649                                 "DoExecute", false, true);
650                         Assert.IsNotNull (e, "#J1");
651                         Assert.AreEqual (102, e (new C ()), "#J2");
652
653                         // ignore case, do not throw bind failure
654                         e = (E) Delegate.CreateDelegate (typeof (E), new C (),
655                                 "DoExecute", true, false);
656                         Assert.IsNotNull (e, "#K1");
657                         Assert.AreEqual (102, e (new C ()), "#K2");
658
659                         // ignore case, throw bind failure
660                         e = (E) Delegate.CreateDelegate (typeof (E), new C (),
661                                 "DoExecute", true, true);
662                         Assert.IsNotNull (e, "#L1");
663                         Assert.AreEqual (102, e (new C ()), "#L2");
664                 }
665
666                 [Test] // CreateDelegate (Type, Object, String, Boolean, Boolean)
667                 public void CreateDelegate9_Method_ArgumentsMismatch ()
668                 {
669                         // throw bind failure
670                         try {
671                                 Delegate.CreateDelegate (typeof (E), new B (),
672                                         "StartExecute", false, true);
673                                 Assert.Fail ("#A1");
674                         } catch (ArgumentException ex) {
675                                 // Error binding to target method
676                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#A2");
677                                 Assert.IsNull (ex.InnerException, "#A3");
678                                 Assert.IsNotNull (ex.Message, "#A4");
679                                 Assert.IsNull (ex.ParamName, "#A5");
680                         }
681
682                         // do not throw on bind failure
683                         E e = (E) Delegate.CreateDelegate (typeof (E), new B (),
684                                 "StartExecute", false, false);
685                         Assert.IsNull (e, "#B");
686                 }
687
688                 [Test] // CreateDelegate (Type, Object, String, Boolean, Boolean)
689                 public void CreateDelegate9_Method_CaseMismatch ()
690                 {
691                         E e;
692
693                         // do not ignore case, throw bind failure
694                         try {
695                                 Delegate.CreateDelegate (typeof (E), new B (),
696                                         "ExecutE", false, true);
697                                 Assert.Fail ("#A1");
698                         } catch (ArgumentException ex) {
699                                 // Error binding to target method
700                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#A2");
701                                 Assert.IsNull (ex.InnerException, "#A3");
702                                 Assert.IsNotNull (ex.Message, "#A4");
703                                 Assert.IsNull (ex.ParamName, "#A5");
704                         }
705
706                         // do not ignore case, do not throw bind failure
707                         e = (E) Delegate.CreateDelegate (typeof (E), new B (),
708                                 "ExecutE", false, false);
709                         Assert.IsNull (e, "#B");
710
711                         // ignore case, throw bind failure
712                         e = (E) Delegate.CreateDelegate (typeof (E), new B (),
713                                 "ExecutE", true, true);
714                         Assert.IsNotNull (e, "#C1");
715                         Assert.AreEqual (4, e (new C ()), "#C2");
716
717                         // ignore case, do not throw bind failure
718                         e = (E) Delegate.CreateDelegate (typeof (E), new B (),
719                                 "ExecutE", true, false);
720                         Assert.IsNotNull (e, "#D1");
721                         Assert.AreEqual (4, e (new C ()), "#D2");
722                 }
723
724                 [Test] // CreateDelegate (Type, Object, String, Boolean, Boolean)
725                 public void CreateDelegate9_Method_DoesNotExist ()
726                 {
727                         // throw bind failure
728                         try {
729                                 Delegate.CreateDelegate (typeof (E), new B (),
730                                         "DoesNotExist", false, true);
731                                 Assert.Fail ("#A1");
732                         } catch (ArgumentException ex) {
733                                 // Error binding to target method
734                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#A2");
735                                 Assert.IsNull (ex.InnerException, "#A3");
736                                 Assert.IsNotNull (ex.Message, "#A4");
737                                 Assert.IsNull (ex.ParamName, "#A5");
738                         }
739
740                         // do not throw on bind failure
741                         E e = (E) Delegate.CreateDelegate (typeof (E), new B (),
742                                 "DoesNotExist", false, false);
743                         Assert.IsNull (e, "#B");
744                 }
745
746                 [Test] // CreateDelegate (Type, Object, String, Boolean, Boolean)
747                 public void CreateDelegate9_Method_Null ()
748                 {
749                         try {
750                                 Delegate.CreateDelegate (typeof (E), new B (),
751                                         (string) null, false, false);
752                                 Assert.Fail ("#1");
753                         } catch (ArgumentNullException ex) {
754                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
755                                 Assert.IsNull (ex.InnerException, "#3");
756                                 Assert.IsNotNull (ex.Message, "#4");
757                                 Assert.IsNotNull (ex.ParamName, "#5");
758                                 Assert.AreEqual ("method", ex.ParamName, "#6");
759                         }
760                 }
761
762                 [Test] // CreateDelegate (Type, Object, String, Boolean, Boolean)
763                 public void CreateDelegate9_Method_ReturnTypeMismatch ()
764                 {
765                         // throw bind failure
766                         try {
767                                 Delegate.CreateDelegate (typeof (E), new B (),
768                                         "DoExecute", false, true);
769                                 Assert.Fail ("#A1");
770                         } catch (ArgumentException ex) {
771                                 // Error binding to target method
772                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#A2");
773                                 Assert.IsNull (ex.InnerException, "#A3");
774                                 Assert.IsNotNull (ex.Message, "#A4");
775                                 Assert.IsNull (ex.ParamName, "#A5");
776                         }
777
778                         // do not throw on bind failure
779                         E e = (E) Delegate.CreateDelegate (typeof (E), new B (),
780                                 "DoExecute", false, false);
781                         Assert.IsNull (e, "#B");
782                 }
783
784                 [Test] // CreateDelegate (Type, Object, String, Boolean, Boolean)
785                 public void CreateDelegate9_Method_Static ()
786                 {
787                         // throw bind failure
788                         try {
789                                 Delegate.CreateDelegate (typeof (E), new B (),
790                                         "Run", true, true);
791                                 Assert.Fail ("#A1");
792                         } catch (ArgumentException ex) {
793                                 // Error binding to target method
794                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#A2");
795                                 Assert.IsNull (ex.InnerException, "#A3");
796                                 Assert.IsNotNull (ex.Message, "#A4");
797                                 Assert.IsNull (ex.ParamName, "#A5");
798                         }
799
800                         // do not throw on bind failure
801                         E e = (E) Delegate.CreateDelegate (typeof (E), new B (),
802                                 "Run", true, false);
803                         Assert.IsNull (e, "#B");
804                 }
805
806                 [Test] // CreateDelegate (Type, Object, String, Boolean, Boolean)
807                 public void CreateDelegate9_Target_Null ()
808                 {
809                         try {
810                                 Delegate.CreateDelegate (typeof (E),(object) null,
811                                         "Execute", true, false);
812                                 Assert.Fail ("#1");
813                         } catch (ArgumentNullException ex) {
814                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
815                                 Assert.IsNull (ex.InnerException, "#3");
816                                 Assert.IsNotNull (ex.Message, "#4");
817                                 Assert.IsNotNull (ex.ParamName, "#5");
818                                 Assert.AreEqual ("target", ex.ParamName, "#6");
819                         }
820                 }
821
822                 [Test] // CreateDelegate (Type, Object, String, Boolean)
823                 public void CreateDelegate9_Type_Null ()
824                 {
825                         try {
826                                 Delegate.CreateDelegate ((Type) null, new B (),
827                                         "Execute", true, false);
828                                 Assert.Fail ("#1");
829                         } catch (ArgumentNullException ex) {
830                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
831                                 Assert.IsNull (ex.InnerException, "#3");
832                                 Assert.IsNotNull (ex.Message, "#4");
833                                 Assert.IsNotNull (ex.ParamName, "#5");
834                                 Assert.AreEqual ("type", ex.ParamName, "#6");
835                         }
836                 }
837
838                 class ParentClass
839                 {
840                 }
841
842                 class Subclass : ParentClass
843                 {
844                 }
845
846                 delegate ParentClass CoContraVariantDelegate (Subclass s);
847
848                 static Subclass CoContraVariantMethod (ParentClass s)
849                 {
850                         return null;
851                 }
852
853                 [Test]
854                 [Category ("TargetJvmNotWorking")]
855                 public void CoContraVariance ()
856                 {
857                         CoContraVariantDelegate d = (CoContraVariantDelegate)
858                                 Delegate.CreateDelegate (typeof (CoContraVariantDelegate),
859                                         typeof (DelegateTest).GetMethod ("CoContraVariantMethod",
860                                         BindingFlags.NonPublic|BindingFlags.Static));
861                         d (null);
862                 }
863
864                 static object Box (object o)
865                 {
866                         return o;
867                 }
868
869                 delegate object Boxer ();
870
871                 [Test]
872                 public void BoxingCovariance ()
873                 {
874                         var boxer = (Boxer) Delegate.CreateDelegate (
875                                 typeof (Boxer),
876                                 42,
877                                 GetType ().GetMethod ("Box", BindingFlags.NonPublic | BindingFlags.Static));
878
879                         Assert.IsNotNull (boxer);
880                         Assert.AreEqual (42, boxer ());
881                 }
882
883                 static object Nada (int o)
884                 {
885                         return (int) o;
886                 }
887
888                 delegate int WrongDelegate ();
889
890                 [Test]
891                 [ExpectedException (typeof (ArgumentException))]
892                 public void RemoveDelegateTypeMismatch ()
893                 {
894                         Delegate boxer = new Boxer (() => new object ());
895                         Delegate.Remove (boxer, new WrongDelegate (() => 42));
896                 }
897
898                 [Test]
899                 [ExpectedException (typeof (ArgumentException))]
900                 public void WrongReturnTypeContravariance ()
901                 {
902                         Delegate.CreateDelegate (
903                                 typeof (WrongDelegate),
904                                 42,
905                                 GetType ().GetMethod ("Nada", BindingFlags.NonPublic | BindingFlags.Static));
906                 }
907
908                 static int Identity (int i)
909                 {
910                         return i;
911                 }
912
913                 [Test]
914                 [ExpectedException (typeof (ArgumentException))]
915                 public void WrongReturnTypeContravariance_2 ()
916                 {
917                         Delegate.CreateDelegate (
918                                 typeof (Boxer),
919                                 42,
920                                 GetType ().GetMethod ("Identity", BindingFlags.NonPublic | BindingFlags.Static));
921                 }
922
923                 delegate object CallTarget ();
924
925                 class Closure {}
926
927                 static object Target (Closure c)
928                 {
929                         return c;
930                 }
931
932                 [Test]
933                 public void NullFirstArgumentOnStaticMethod ()
934                 {
935                         CallTarget call = (CallTarget) Delegate.CreateDelegate (
936                                 typeof (CallTarget),
937                                 null,
938                                 GetType ().GetMethod ("Target", BindingFlags.NonPublic | BindingFlags.Static));
939
940                         Assert.IsNotNull (call);
941                         Assert.IsNull (call.Target);
942                         Assert.IsNull (call ());
943                 }
944
945                 [Test]
946 #if MONOTOUCH
947                 [Category ("NotWorking")] // #10539
948 #endif
949                 public void Virtual ()
950                 {
951                         // Delegate with abstract method, no target
952                         FooDelegate del = (FooDelegate)Delegate.CreateDelegate (typeof (FooDelegate), typeof (Iface).GetMethod ("retarg"));
953                         C c = new C ();
954                         Assert.AreEqual ("Hello", del (c, "Hello"));
955
956                         // Combination with normal delegates
957                         FooDelegate del2 = (FooDelegate)Delegate.CreateDelegate (typeof (FooDelegate), typeof (Iface).GetMethod ("retarg"));
958                         FooDelegate del3 = new FooDelegate (c.retarg2);
959                         FooDelegate del4 = (FooDelegate)Delegate.Combine (del2, del3);
960
961                         Assert.AreEqual ("Hello2", del4 (c, "Hello"));
962
963                         // Delegate with virtual method, no target
964                         FooDelegate2 del5 = (FooDelegate2)Delegate.CreateDelegate (typeof (FooDelegate2), typeof (B).GetMethod ("retarg3"));
965                         Assert.AreEqual ("Hello2", del5 (c, "Hello"));
966                 }
967
968                 int int_field;
969
970                 delegate int Del1 (DelegateTest dt, int i);
971
972                 public int method1 (int i) {
973                         return int_field + i;
974                 }
975
976                 [Test]
977 #if MONOTOUCH
978                 [Category ("NotWorking")] // #14163
979 #endif
980                 public void NullTarget_Instance ()
981                 {
982                         Del1 d = (Del1)Delegate.CreateDelegate (typeof (Del1), null, typeof (DelegateTest).GetMethod ("method1"));
983
984                         DelegateTest dt = new DelegateTest ();
985                         dt.int_field = 5;
986
987                         Assert.AreEqual (10, d (dt, 5));
988                 }
989
990                 delegate int Del2 (int i);
991
992                 public static int method2 (int i) {
993                         return i + 5;
994                 }
995
996                 [Test]
997                 public void NullTarget_Static ()
998                 {
999                         Del2 d = (Del2)Delegate.CreateDelegate (typeof (Del2), null, typeof (DelegateTest).GetMethod ("method2"));
1000
1001                         Assert.AreEqual (10, d (5));
1002                 }
1003
1004                 delegate int Del3 (int i);
1005
1006                 public int method3 (int i) {
1007                         return int_field + 5;
1008                 }
1009
1010                 [Test]
1011                 public void HasTarget_Instance ()
1012                 {
1013                         DelegateTest dt = new DelegateTest ();
1014                         dt.int_field = 5;
1015
1016                         Del3 d = (Del3)Delegate.CreateDelegate (typeof (Del3), dt, typeof (DelegateTest).GetMethod ("method3"));
1017
1018                         Assert.AreEqual (10, d (5));
1019                 }
1020
1021                 delegate int Del4 (int i);
1022
1023                 public static int method4 (string s, int i) {
1024                         return Int32.Parse (s) + 5;
1025                 }
1026
1027                 [Test]
1028                 public void HasTarget_Static ()
1029                 {
1030                         Del4 d = (Del4)Delegate.CreateDelegate (typeof (Del4), "5", typeof (DelegateTest).GetMethod ("method4"));
1031
1032                         Assert.AreEqual (10, d (5));
1033                 }
1034
1035                 public static long? StaticMethodToBeClosedOverNull (object o, long? bar)
1036                 {
1037                         Console.WriteLine ("o: {0}", o);
1038                         return 5;
1039                 }
1040
1041                 [Test] // #617161
1042 #if MONOTOUCH
1043                 [Category ("NotWorking")] // #10539
1044 #endif
1045                 public void ClosedOverNullReferenceStaticMethod ()
1046                 {
1047                         var del = (Func<long?,long?>) Delegate.CreateDelegate (
1048                                 typeof (Func<long?,long?>),
1049                                 null as object,
1050                                 this.GetType ().GetMethod ("StaticMethodToBeClosedOverNull"));
1051
1052                         Assert.IsNull (del.Target);
1053
1054                         Assert.AreEqual ((long?) 5, del (5));
1055                 }
1056
1057                 public void InstanceMethodToBeClosedOverNull ()
1058                 {
1059                 }
1060
1061                 public void InstanceMethodIntToBeClosedOverNull (int i)
1062                 {
1063                 }
1064
1065                 [Test] // #475962
1066 #if MONOTOUCH
1067                 [Category ("NotWorking")] // #10539
1068 #endif
1069                 public void ClosedOverNullReferenceInstanceMethod ()
1070                 {
1071                         var action = (Action) Delegate.CreateDelegate (
1072                                 typeof (Action),
1073                                 null as object,
1074                                 this.GetType ().GetMethod ("InstanceMethodToBeClosedOverNull"));
1075
1076                         Assert.IsNull (action.Target);
1077
1078                         action ();
1079
1080                         var action_int = (Action<int>) Delegate.CreateDelegate (
1081                                 typeof (Action<int>),
1082                                 null as object,
1083                                 this.GetType ().GetMethod ("InstanceMethodIntToBeClosedOverNull"));
1084
1085                         Assert.IsNull (action.Target);
1086
1087                         action_int (42);
1088                 }
1089
1090                 class Foo {
1091
1092                         public void Bar ()
1093                         {
1094                         }
1095                 }
1096
1097                 Foo foo;
1098                 event Action bar_handler;
1099
1100                 [Test]
1101                 [ExpectedException (typeof (ArgumentException))] // #635349, #605936
1102                 public void NewDelegateClosedOverNullReferenceInstanceMethod ()
1103                 {
1104                         bar_handler += foo.Bar;
1105                 }
1106
1107                 public void Banga ()
1108                 {
1109                 }
1110
1111                 [Test]
1112                 [ExpectedException (typeof (ArgumentException))]
1113                 public void CreateDelegateOpenOnly ()
1114                 {
1115                         Delegate.CreateDelegate (
1116                                 typeof (Action),
1117                                 this.GetType ().GetMethod ("Banga"));
1118                 }
1119 #if !MONOTOUCH
1120                 [Test] // #664205
1121                 public void DynamicInvokeNullTarget ()
1122                 {
1123                         var method = new DynamicMethod ("test", typeof (int), new [] { typeof (object) }, true);
1124                         var il = method.GetILGenerator ();
1125                         il.Emit (OpCodes.Ldc_I4, 42);
1126                         il.Emit (OpCodes.Ret);
1127
1128                         var @delegate = method.CreateDelegate (typeof (Func<int>), null);
1129
1130                         Assert.AreEqual (42, (int) @delegate.DynamicInvoke ());
1131                 }
1132 #endif
1133 #endif
1134                 public static void CreateDelegateOfStaticMethodBoundToNull_Helper (object[] args) {}
1135
1136                 [Test]
1137                 public void CreateDelegateOfStaticMethodBoundToNull ()
1138                 {
1139                         Type t = typeof (Action);
1140                         MethodInfo m = typeof (DelegateTest).GetMethod ("CreateDelegateOfStaticMethodBoundToNull_Helper");
1141                         object firstArg = null;
1142         
1143                         try {
1144                                 Delegate.CreateDelegate (t, m) ;
1145                                 Assert.Fail ("#1");
1146                         } catch (ArgumentException) {  }
1147         
1148                         try {
1149                                 Delegate.CreateDelegate(t, m, true);
1150                                 Assert.Fail ("#2");
1151                         } catch (ArgumentException) {  }
1152         
1153                         try {
1154                                 Delegate.CreateDelegate(t, m, false);
1155                         } catch (ArgumentException) { Assert.Fail ("#3"); }
1156         
1157                         try {
1158                                 Delegate.CreateDelegate(t, null, m);
1159                         } catch (ArgumentException) { Assert.Fail ("#4"); }
1160         
1161                         try {
1162                                 Delegate.CreateDelegate(t, null, m, true);
1163                         } catch (ArgumentException) { Assert.Fail ("#5");  }
1164         
1165                         try {
1166                                 Delegate.CreateDelegate(t, null, m, false);
1167                         } catch (ArgumentException) { Assert.Fail ("#6"); }
1168                 }
1169
1170                 [Test]
1171                 public void GetHashCode_Constant () {
1172                         Action del = delegate {
1173                         };
1174                         int hc1 = del.GetHashCode ();
1175                         del ();
1176                         int hc2 = del.GetHashCode ();
1177                         Assert.AreEqual (hc1, hc2);
1178                 }
1179
1180                 public interface CreateDelegateIFoo {
1181                         int Test2 ();
1182                 }
1183                 
1184                 public abstract class CreateDelegateFoo {
1185                         public abstract int Test ();
1186                 }
1187                 
1188                 public class CreateDelegateMid : CreateDelegateFoo {
1189                         public override int Test () {
1190                                 return 1;
1191                         }
1192                 }
1193                 
1194                 public class CreateDelegateBar : CreateDelegateMid, CreateDelegateIFoo {
1195                         public override int Test () {
1196                                 return 2;
1197                         }
1198                 
1199                         public int Test2 () {
1200                                 return 3;
1201                         }
1202                 }
1203         
1204                 delegate int IntNoArgs ();
1205
1206                 [Test]
1207                 public void CreateDelegateWithAbstractMethods ()
1208                 {
1209                         var f = new CreateDelegateBar ();
1210                         var m = typeof (CreateDelegateFoo).GetMethod ("Test");
1211                         var m2 = typeof (CreateDelegateMid).GetMethod ("Test");
1212                         var m3 = typeof (CreateDelegateIFoo).GetMethod ("Test2");
1213         
1214                         IntNoArgs a1 = (IntNoArgs)Delegate.CreateDelegate (typeof (IntNoArgs), f, m);
1215                         IntNoArgs a2 = (IntNoArgs)Delegate.CreateDelegate (typeof (IntNoArgs), f, m2);
1216                         IntNoArgs a3 = (IntNoArgs)Delegate.CreateDelegate (typeof (IntNoArgs), f, m3);
1217
1218                         Assert.AreEqual (2, a1 (), "#1");
1219                         Assert.AreEqual (2, a2 (), "#2");
1220                         Assert.AreEqual (3, a3 (), "#3");
1221                 }
1222                 
1223
1224                 delegate string FooDelegate (Iface iface, string s);
1225
1226                 delegate string FooDelegate2 (B b, string s);
1227
1228                 public interface Iface
1229                 {
1230                         string retarg (string s);
1231                 }
1232 #if !MONOTOUCH
1233                 [Test]
1234                 public void CreateDelegateWithLdFtnAndAbstractMethod ()
1235                 {
1236                         AssemblyName assemblyName = new AssemblyName ();
1237                         assemblyName.Name = "customMod";
1238                         assemblyName.Version = new Version (1, 2, 3, 4);
1239         
1240                         AssemblyBuilder assembly
1241                                 = Thread.GetDomain ().DefineDynamicAssembly (
1242                                           assemblyName, AssemblyBuilderAccess.RunAndSave);
1243         
1244                         ModuleBuilder module = assembly.DefineDynamicModule ("res", "res.dll");
1245         
1246                         TypeBuilder tb = module.DefineType ("Test2", TypeAttributes.Public, typeof (object));
1247         
1248                         {
1249                                 MethodBuilder mb =
1250                                         tb.DefineMethod ("test", MethodAttributes.Public | MethodAttributes.Static,
1251                                                                          typeof (int), null);
1252                                 ILGenerator il = mb.GetILGenerator ();
1253         
1254                                 il.Emit (OpCodes.Newobj, typeof (CreateDelegateBar).GetConstructor (new Type [] { }));
1255                                 il.Emit (OpCodes.Ldftn, typeof (CreateDelegateIFoo).GetMethod ("Test2"));
1256                                 il.Emit (OpCodes.Newobj, typeof (IntNoArgs).GetConstructor (new Type [] { typeof (object), typeof (IntPtr) }));
1257                                 il.Emit (OpCodes.Call, typeof (IntNoArgs).GetMethod ("Invoke"));
1258                                 il.Emit (OpCodes.Ret);
1259                         }
1260         
1261                         Type t = tb.CreateType ();
1262         
1263                         Object obj = Activator.CreateInstance (t, new object [0] { });
1264         
1265                         int a = (int) t.GetMethod ("test").Invoke (obj, null);
1266                         Assert.AreEqual (3, a, "#1");
1267                 }
1268 #endif
1269                 public static int MethodWithIntParam (int x) {
1270                         return 10;
1271                 }
1272
1273                 [Test]
1274                 [Category("NotWorking")]
1275                 public void CantBindValueTypeToFirstArg () {
1276                         try {
1277                                 Delegate.CreateDelegate (typeof (Delegate695978_2), 10, typeof (DelegateTest).GetMethod ("MethodWithIntParam"));
1278                                 Assert.Fail ("create delegate must fail");
1279                         } catch (ArgumentException) {}
1280                 }
1281
1282                 struct Struct695978 {
1283                         public int value;
1284                         public int test() { return value + 10; }
1285                         public static int test2 (ref Struct695978 foo) { return foo.value + 20; }
1286                 }
1287
1288                 delegate int Delegate695978_1 (ref Struct695978 _this);
1289                 delegate int Delegate695978_2 ();
1290                 delegate int Delegate695978_3 (Struct695978 _this);
1291
1292                 [Test] //tests for #695978
1293                 [Category ("NotWorking")]
1294                 public void DelegateWithValueTypeArguments ()
1295                 {
1296                         Struct695978 es = new Struct695978 ();
1297                         es.value = 100;
1298
1299                         var ar1 = (Delegate695978_1)Delegate.CreateDelegate(typeof (Delegate695978_1), typeof (Struct695978).GetMethod("test"));
1300                         Assert.IsNotNull (ar1);
1301                         Assert.AreEqual (110, ar1 (ref es));
1302
1303                         var ar2 = (Delegate695978_2)Delegate.CreateDelegate(typeof (Delegate695978_2), null, typeof (Struct695978).GetMethod("test"));
1304                         Assert.IsNotNull (ar2);
1305                         Assert.AreEqual (110, ar2 ());
1306
1307                         ar1 = (Delegate695978_1) Delegate.CreateDelegate(typeof (Delegate695978_1), typeof (Struct695978).GetMethod("test2"));
1308                         Assert.IsNotNull (ar1);
1309                         Assert.AreEqual (120, ar1 (ref es));
1310
1311                         try {
1312                                 Delegate.CreateDelegate(typeof (Delegate695978_2), null, typeof (Struct695978).GetMethod("test2"));
1313                                 Assert.Fail ("#1");
1314                         } catch (ArgumentException) {}
1315
1316
1317                         ar2 = (Delegate695978_2) Delegate.CreateDelegate(typeof (Delegate695978_2), new Struct695978 (), typeof (Struct695978).GetMethod("test"));
1318                         Assert.IsNotNull (ar2);
1319                         Assert.AreEqual (120, ar2 ());
1320
1321                         try {
1322                                 Delegate.CreateDelegate(typeof (Delegate695978_2), new Struct695978 (), typeof (Struct695978).GetMethod("test2"));
1323                                 Assert.Fail ("#2");
1324                         } catch (ArgumentException) {}
1325
1326                         try {
1327                                 Delegate.CreateDelegate(typeof (Delegate695978_3), typeof (Struct695978).GetMethod("test"));
1328                                 Assert.Fail ("#3");
1329                         } catch (ArgumentException) {}
1330                 }
1331
1332         private static Func<Int32, Int32, bool> Int32D = (x, y) => (x & y) == y;
1333
1334                 [Test]
1335                 public void EnumBaseTypeConversion () {
1336                         var d =
1337                                 Delegate.CreateDelegate(typeof (Func<StringComparison,
1338                                                                                                 StringComparison, bool>), Int32D.Method) as
1339                                 Func<StringComparison, StringComparison, bool>; 
1340                         Assert.IsTrue (d (0, 0));
1341                 }
1342
1343                 public class B {
1344
1345                         public virtual string retarg3 (string s) {
1346                                 return s;
1347                         }
1348
1349                         static int Run (C x)
1350                         {
1351                                 return 5;
1352                         }
1353
1354                         public static void DoRun (C x)
1355                         {
1356                         }
1357
1358                         public static int StartRun (C x, B b)
1359                         {
1360                                 return 6;
1361                         }
1362
1363                         int Execute (C c)
1364                         {
1365                                 return 4;
1366                         }
1367
1368                         public void DoExecute (C c)
1369                         {
1370                         }
1371
1372                         public int StartExecute (C c, B b)
1373                         {
1374                                 return 3;
1375                         }
1376                 }
1377
1378                 public class C : B, Iface
1379                 {
1380                         public string retarg (string s) {
1381                                 return s;
1382                         }
1383
1384                         public string retarg2 (Iface iface, string s) {
1385                                 return s + "2";
1386                         }
1387
1388                         public override string retarg3 (string s) {
1389                                 return s + "2";
1390                         }
1391
1392                         static void Run (C x)
1393                         {
1394                         }
1395
1396                         public new static int DoRun (C x)
1397                         {
1398                                 return 107;
1399                         }
1400
1401                         void Execute (C c)
1402                         {
1403                         }
1404
1405                         public new int DoExecute (C c)
1406                         {
1407                                 return 102;
1408                         }
1409
1410                         public void M ()
1411                         {
1412                         }
1413
1414                         public void N (C c)
1415                         {
1416                         }
1417
1418                         public static void S (C c)
1419                         {
1420                         }
1421
1422                         private void PrivateInstance ()
1423                         {
1424                         }
1425                 }
1426
1427                 public delegate void D (C c);
1428                 public delegate int E (C c);
1429         }
1430 }