[Cleanup] Removed TARGET_JVM
[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                 public void CoContraVariance ()
855                 {
856                         CoContraVariantDelegate d = (CoContraVariantDelegate)
857                                 Delegate.CreateDelegate (typeof (CoContraVariantDelegate),
858                                         typeof (DelegateTest).GetMethod ("CoContraVariantMethod",
859                                         BindingFlags.NonPublic|BindingFlags.Static));
860                         d (null);
861                 }
862
863                 static object Box (object o)
864                 {
865                         return o;
866                 }
867
868                 delegate object Boxer ();
869
870                 [Test]
871                 public void BoxingCovariance ()
872                 {
873                         var boxer = (Boxer) Delegate.CreateDelegate (
874                                 typeof (Boxer),
875                                 42,
876                                 GetType ().GetMethod ("Box", BindingFlags.NonPublic | BindingFlags.Static));
877
878                         Assert.IsNotNull (boxer);
879                         Assert.AreEqual (42, boxer ());
880                 }
881
882                 static object Nada (int o)
883                 {
884                         return (int) o;
885                 }
886
887                 delegate int WrongDelegate ();
888
889                 [Test]
890                 [ExpectedException (typeof (ArgumentException))]
891                 public void RemoveDelegateTypeMismatch ()
892                 {
893                         Delegate boxer = new Boxer (() => new object ());
894                         Delegate.Remove (boxer, new WrongDelegate (() => 42));
895                 }
896
897                 [Test]
898                 [ExpectedException (typeof (ArgumentException))]
899                 public void WrongReturnTypeContravariance ()
900                 {
901                         Delegate.CreateDelegate (
902                                 typeof (WrongDelegate),
903                                 42,
904                                 GetType ().GetMethod ("Nada", BindingFlags.NonPublic | BindingFlags.Static));
905                 }
906
907                 static int Identity (int i)
908                 {
909                         return i;
910                 }
911
912                 [Test]
913                 [ExpectedException (typeof (ArgumentException))]
914                 public void WrongReturnTypeContravariance_2 ()
915                 {
916                         Delegate.CreateDelegate (
917                                 typeof (Boxer),
918                                 42,
919                                 GetType ().GetMethod ("Identity", BindingFlags.NonPublic | BindingFlags.Static));
920                 }
921
922                 delegate object CallTarget ();
923
924                 class Closure {}
925
926                 static object Target (Closure c)
927                 {
928                         return c;
929                 }
930
931                 [Test]
932                 public void NullFirstArgumentOnStaticMethod ()
933                 {
934                         CallTarget call = (CallTarget) Delegate.CreateDelegate (
935                                 typeof (CallTarget),
936                                 null,
937                                 GetType ().GetMethod ("Target", BindingFlags.NonPublic | BindingFlags.Static));
938
939                         Assert.IsNotNull (call);
940                         Assert.IsNull (call.Target);
941                         Assert.IsNull (call ());
942                 }
943
944                 [Test]
945 #if MONOTOUCH
946                 [Category ("NotWorking")] // #10539
947 #endif
948                 public void Virtual ()
949                 {
950                         // Delegate with abstract method, no target
951                         FooDelegate del = (FooDelegate)Delegate.CreateDelegate (typeof (FooDelegate), typeof (Iface).GetMethod ("retarg"));
952                         C c = new C ();
953                         Assert.AreEqual ("Hello", del (c, "Hello"));
954
955                         // Combination with normal delegates
956                         FooDelegate del2 = (FooDelegate)Delegate.CreateDelegate (typeof (FooDelegate), typeof (Iface).GetMethod ("retarg"));
957                         FooDelegate del3 = new FooDelegate (c.retarg2);
958                         FooDelegate del4 = (FooDelegate)Delegate.Combine (del2, del3);
959
960                         Assert.AreEqual ("Hello2", del4 (c, "Hello"));
961
962                         // Delegate with virtual method, no target
963                         FooDelegate2 del5 = (FooDelegate2)Delegate.CreateDelegate (typeof (FooDelegate2), typeof (B).GetMethod ("retarg3"));
964                         Assert.AreEqual ("Hello2", del5 (c, "Hello"));
965                 }
966
967                 int int_field;
968
969                 delegate int Del1 (DelegateTest dt, int i);
970
971                 public int method1 (int i) {
972                         return int_field + i;
973                 }
974
975                 [Test]
976 #if MONOTOUCH
977                 [Category ("NotWorking")] // #14163
978 #endif
979                 public void NullTarget_Instance ()
980                 {
981                         Del1 d = (Del1)Delegate.CreateDelegate (typeof (Del1), null, typeof (DelegateTest).GetMethod ("method1"));
982
983                         DelegateTest dt = new DelegateTest ();
984                         dt.int_field = 5;
985
986                         Assert.AreEqual (10, d (dt, 5));
987                 }
988
989                 delegate int Del2 (int i);
990
991                 public static int method2 (int i) {
992                         return i + 5;
993                 }
994
995                 [Test]
996                 public void NullTarget_Static ()
997                 {
998                         Del2 d = (Del2)Delegate.CreateDelegate (typeof (Del2), null, typeof (DelegateTest).GetMethod ("method2"));
999
1000                         Assert.AreEqual (10, d (5));
1001                 }
1002
1003                 delegate int Del3 (int i);
1004
1005                 public int method3 (int i) {
1006                         return int_field + 5;
1007                 }
1008
1009                 [Test]
1010                 public void HasTarget_Instance ()
1011                 {
1012                         DelegateTest dt = new DelegateTest ();
1013                         dt.int_field = 5;
1014
1015                         Del3 d = (Del3)Delegate.CreateDelegate (typeof (Del3), dt, typeof (DelegateTest).GetMethod ("method3"));
1016
1017                         Assert.AreEqual (10, d (5));
1018                 }
1019
1020                 delegate int Del4 (int i);
1021
1022                 public static int method4 (string s, int i) {
1023                         return Int32.Parse (s) + 5;
1024                 }
1025
1026                 [Test]
1027                 public void HasTarget_Static ()
1028                 {
1029                         Del4 d = (Del4)Delegate.CreateDelegate (typeof (Del4), "5", typeof (DelegateTest).GetMethod ("method4"));
1030
1031                         Assert.AreEqual (10, d (5));
1032                 }
1033
1034                 public static long? StaticMethodToBeClosedOverNull (object o, long? bar)
1035                 {
1036                         Console.WriteLine ("o: {0}", o);
1037                         return 5;
1038                 }
1039
1040                 [Test] // #617161
1041 #if MONOTOUCH
1042                 [Category ("NotWorking")] // #10539
1043 #endif
1044                 public void ClosedOverNullReferenceStaticMethod ()
1045                 {
1046                         var del = (Func<long?,long?>) Delegate.CreateDelegate (
1047                                 typeof (Func<long?,long?>),
1048                                 null as object,
1049                                 this.GetType ().GetMethod ("StaticMethodToBeClosedOverNull"));
1050
1051                         Assert.IsNull (del.Target);
1052
1053                         Assert.AreEqual ((long?) 5, del (5));
1054                 }
1055
1056                 public void InstanceMethodToBeClosedOverNull ()
1057                 {
1058                 }
1059
1060                 public void InstanceMethodIntToBeClosedOverNull (int i)
1061                 {
1062                 }
1063
1064                 [Test] // #475962
1065 #if MONOTOUCH
1066                 [Category ("NotWorking")] // #10539
1067 #endif
1068                 public void ClosedOverNullReferenceInstanceMethod ()
1069                 {
1070                         var action = (Action) Delegate.CreateDelegate (
1071                                 typeof (Action),
1072                                 null as object,
1073                                 this.GetType ().GetMethod ("InstanceMethodToBeClosedOverNull"));
1074
1075                         Assert.IsNull (action.Target);
1076
1077                         action ();
1078
1079                         var action_int = (Action<int>) Delegate.CreateDelegate (
1080                                 typeof (Action<int>),
1081                                 null as object,
1082                                 this.GetType ().GetMethod ("InstanceMethodIntToBeClosedOverNull"));
1083
1084                         Assert.IsNull (action.Target);
1085
1086                         action_int (42);
1087                 }
1088
1089                 class Foo {
1090
1091                         public void Bar ()
1092                         {
1093                         }
1094                 }
1095
1096                 Foo foo;
1097                 event Action bar_handler;
1098
1099                 [Test]
1100                 [ExpectedException (typeof (ArgumentException))] // #635349, #605936
1101                 public void NewDelegateClosedOverNullReferenceInstanceMethod ()
1102                 {
1103                         bar_handler += foo.Bar;
1104                 }
1105
1106                 public void Banga ()
1107                 {
1108                 }
1109
1110                 [Test]
1111                 [ExpectedException (typeof (ArgumentException))]
1112                 public void CreateDelegateOpenOnly ()
1113                 {
1114                         Delegate.CreateDelegate (
1115                                 typeof (Action),
1116                                 this.GetType ().GetMethod ("Banga"));
1117                 }
1118
1119                 [Test] // #664205
1120                 public void DynamicInvokeClosedStatic ()
1121                 {
1122                         var d1 = Delegate.CreateDelegate (typeof(Func<int>), null, typeof(DelegateTest).GetMethod ("DynamicInvokeClosedStaticDelegate_CB"));
1123                         Assert.AreEqual (1, d1.DynamicInvoke (), "#1");
1124
1125                         var d2 = Delegate.CreateDelegate (typeof(Func<int>), "arg", typeof(DelegateTest).GetMethod ("DynamicInvokeClosedStaticDelegate_CB"));
1126                         Assert.AreEqual (2, d2.DynamicInvoke (), "#2");
1127                 }
1128
1129                 public static int DynamicInvokeClosedStaticDelegate_CB (string instance)
1130                 {
1131                         switch (instance) {
1132                         case null:
1133                                 return 1;
1134                         case "arg":
1135                                 return 2;
1136                         default:
1137                                 Assert.Fail ();
1138                                 return -1;
1139                         }
1140                 }
1141
1142                 [Test]
1143                 public void DynamicInvokeOpenInstanceDelegate ()
1144                 {
1145                         var d1 = Delegate.CreateDelegate (typeof (Func<DelegateTest, int>), typeof(DelegateTest).GetMethod ("DynamicInvokeOpenInstanceDelegate_CB"));
1146                         Assert.AreEqual (5, d1.DynamicInvoke (new DelegateTest ()), "#1");
1147
1148                         var d3 = (Func<DelegateTest, int>) d1;
1149                         Assert.AreEqual (5, d3 (null), "#2");
1150                 }
1151
1152                 public int DynamicInvokeOpenInstanceDelegate_CB ()
1153                 {
1154                         return 5;
1155                 }
1156
1157                 [Test]
1158                 public void DynamicInvoke_InvalidArguments ()
1159                 {
1160                         Delegate d = new Func<int, int> (TestMethod);
1161
1162                         try {
1163                                 d.DynamicInvoke (null);
1164                                 Assert.Fail ("#1");
1165                         } catch (TargetParameterCountException) {
1166                         }
1167
1168                         try {
1169                                 d.DynamicInvoke (new object [0]);
1170                                 Assert.Fail ("#2");
1171                         } catch (TargetParameterCountException) {
1172                         }
1173                 }
1174
1175                 public static int TestMethod (int i)
1176                 {
1177                         throw new NotSupportedException ();
1178                 }
1179
1180 #endif
1181                 public static void CreateDelegateOfStaticMethodBoundToNull_Helper (object[] args) {}
1182
1183                 [Test]
1184                 public void CreateDelegateOfStaticMethodBoundToNull ()
1185                 {
1186                         Type t = typeof (Action);
1187                         MethodInfo m = typeof (DelegateTest).GetMethod ("CreateDelegateOfStaticMethodBoundToNull_Helper");
1188                         object firstArg = null;
1189         
1190                         try {
1191                                 Delegate.CreateDelegate (t, m) ;
1192                                 Assert.Fail ("#1");
1193                         } catch (ArgumentException) {  }
1194         
1195                         try {
1196                                 Delegate.CreateDelegate(t, m, true);
1197                                 Assert.Fail ("#2");
1198                         } catch (ArgumentException) {  }
1199         
1200                         try {
1201                                 Delegate.CreateDelegate(t, m, false);
1202                         } catch (ArgumentException) { Assert.Fail ("#3"); }
1203         
1204                         try {
1205                                 Delegate.CreateDelegate(t, null, m);
1206                         } catch (ArgumentException) { Assert.Fail ("#4"); }
1207         
1208                         try {
1209                                 Delegate.CreateDelegate(t, null, m, true);
1210                         } catch (ArgumentException) { Assert.Fail ("#5");  }
1211         
1212                         try {
1213                                 Delegate.CreateDelegate(t, null, m, false);
1214                         } catch (ArgumentException) { Assert.Fail ("#6"); }
1215                 }
1216
1217                 [Test]
1218                 public void GetHashCode_Constant () {
1219                         Action del = delegate {
1220                         };
1221                         int hc1 = del.GetHashCode ();
1222                         del ();
1223                         int hc2 = del.GetHashCode ();
1224                         Assert.AreEqual (hc1, hc2);
1225                 }
1226
1227                 public interface CreateDelegateIFoo {
1228                         int Test2 ();
1229                 }
1230                 
1231                 public abstract class CreateDelegateFoo {
1232                         public abstract int Test ();
1233                 }
1234                 
1235                 public class CreateDelegateMid : CreateDelegateFoo {
1236                         public override int Test () {
1237                                 return 1;
1238                         }
1239                 }
1240                 
1241                 public class CreateDelegateBar : CreateDelegateMid, CreateDelegateIFoo {
1242                         public override int Test () {
1243                                 return 2;
1244                         }
1245                 
1246                         public int Test2 () {
1247                                 return 3;
1248                         }
1249                 }
1250         
1251                 delegate int IntNoArgs ();
1252
1253                 [Test]
1254                 public void CreateDelegateWithAbstractMethods ()
1255                 {
1256                         var f = new CreateDelegateBar ();
1257                         var m = typeof (CreateDelegateFoo).GetMethod ("Test");
1258                         var m2 = typeof (CreateDelegateMid).GetMethod ("Test");
1259                         var m3 = typeof (CreateDelegateIFoo).GetMethod ("Test2");
1260         
1261                         IntNoArgs a1 = (IntNoArgs)Delegate.CreateDelegate (typeof (IntNoArgs), f, m);
1262                         IntNoArgs a2 = (IntNoArgs)Delegate.CreateDelegate (typeof (IntNoArgs), f, m2);
1263                         IntNoArgs a3 = (IntNoArgs)Delegate.CreateDelegate (typeof (IntNoArgs), f, m3);
1264
1265                         Assert.AreEqual (2, a1 (), "#1");
1266                         Assert.AreEqual (2, a2 (), "#2");
1267                         Assert.AreEqual (3, a3 (), "#3");
1268                 }
1269                 
1270
1271                 delegate string FooDelegate (Iface iface, string s);
1272
1273                 delegate string FooDelegate2 (B b, string s);
1274
1275                 public interface Iface
1276                 {
1277                         string retarg (string s);
1278                 }
1279 #if !MONOTOUCH
1280                 [Test]
1281                 public void CreateDelegateWithLdFtnAndAbstractMethod ()
1282                 {
1283                         AssemblyName assemblyName = new AssemblyName ();
1284                         assemblyName.Name = "customMod";
1285                         assemblyName.Version = new Version (1, 2, 3, 4);
1286         
1287                         AssemblyBuilder assembly
1288                                 = Thread.GetDomain ().DefineDynamicAssembly (
1289                                           assemblyName, AssemblyBuilderAccess.RunAndSave);
1290         
1291                         ModuleBuilder module = assembly.DefineDynamicModule ("res", "res.dll");
1292         
1293                         TypeBuilder tb = module.DefineType ("Test2", TypeAttributes.Public, typeof (object));
1294         
1295                         {
1296                                 MethodBuilder mb =
1297                                         tb.DefineMethod ("test", MethodAttributes.Public | MethodAttributes.Static,
1298                                                                          typeof (int), null);
1299                                 ILGenerator il = mb.GetILGenerator ();
1300         
1301                                 il.Emit (OpCodes.Newobj, typeof (CreateDelegateBar).GetConstructor (new Type [] { }));
1302                                 il.Emit (OpCodes.Ldftn, typeof (CreateDelegateIFoo).GetMethod ("Test2"));
1303                                 il.Emit (OpCodes.Newobj, typeof (IntNoArgs).GetConstructor (new Type [] { typeof (object), typeof (IntPtr) }));
1304                                 il.Emit (OpCodes.Call, typeof (IntNoArgs).GetMethod ("Invoke"));
1305                                 il.Emit (OpCodes.Ret);
1306                         }
1307         
1308                         Type t = tb.CreateType ();
1309         
1310                         Object obj = Activator.CreateInstance (t, new object [0] { });
1311         
1312                         int a = (int) t.GetMethod ("test").Invoke (obj, null);
1313                         Assert.AreEqual (3, a, "#1");
1314                 }
1315 #endif
1316                 public static int MethodWithIntParam (int x) {
1317                         return 10;
1318                 }
1319
1320                 [Test]
1321                 [Category("NotWorking")]
1322                 public void CantBindValueTypeToFirstArg () {
1323                         try {
1324                                 Delegate.CreateDelegate (typeof (Delegate695978_2), 10, typeof (DelegateTest).GetMethod ("MethodWithIntParam"));
1325                                 Assert.Fail ("create delegate must fail");
1326                         } catch (ArgumentException) {}
1327                 }
1328
1329                 struct Struct695978 {
1330                         public int value;
1331                         public int test() { return value + 10; }
1332                         public static int test2 (ref Struct695978 foo) { return foo.value + 20; }
1333                 }
1334
1335                 delegate int Delegate695978_1 (ref Struct695978 _this);
1336                 delegate int Delegate695978_2 ();
1337                 delegate int Delegate695978_3 (Struct695978 _this);
1338
1339                 [Test] //tests for #695978
1340                 [Category ("NotWorking")]
1341                 public void DelegateWithValueTypeArguments ()
1342                 {
1343                         Struct695978 es = new Struct695978 ();
1344                         es.value = 100;
1345
1346                         var ar1 = (Delegate695978_1)Delegate.CreateDelegate(typeof (Delegate695978_1), typeof (Struct695978).GetMethod("test"));
1347                         Assert.IsNotNull (ar1);
1348                         Assert.AreEqual (110, ar1 (ref es));
1349
1350                         var ar2 = (Delegate695978_2)Delegate.CreateDelegate(typeof (Delegate695978_2), null, typeof (Struct695978).GetMethod("test"));
1351                         Assert.IsNotNull (ar2);
1352                         Assert.AreEqual (110, ar2 ());
1353
1354                         ar1 = (Delegate695978_1) Delegate.CreateDelegate(typeof (Delegate695978_1), typeof (Struct695978).GetMethod("test2"));
1355                         Assert.IsNotNull (ar1);
1356                         Assert.AreEqual (120, ar1 (ref es));
1357
1358                         try {
1359                                 Delegate.CreateDelegate(typeof (Delegate695978_2), null, typeof (Struct695978).GetMethod("test2"));
1360                                 Assert.Fail ("#1");
1361                         } catch (ArgumentException) {}
1362
1363
1364                         ar2 = (Delegate695978_2) Delegate.CreateDelegate(typeof (Delegate695978_2), new Struct695978 (), typeof (Struct695978).GetMethod("test"));
1365                         Assert.IsNotNull (ar2);
1366                         Assert.AreEqual (120, ar2 ());
1367
1368                         try {
1369                                 Delegate.CreateDelegate(typeof (Delegate695978_2), new Struct695978 (), typeof (Struct695978).GetMethod("test2"));
1370                                 Assert.Fail ("#2");
1371                         } catch (ArgumentException) {}
1372
1373                         try {
1374                                 Delegate.CreateDelegate(typeof (Delegate695978_3), typeof (Struct695978).GetMethod("test"));
1375                                 Assert.Fail ("#3");
1376                         } catch (ArgumentException) {}
1377                 }
1378
1379                 [Test]
1380                 public void EnumBaseTypeConversion () {
1381                         Func<int, int, bool> dm = Int32D2;
1382                         var d =
1383                                 Delegate.CreateDelegate(typeof (Func<StringComparison, StringComparison, bool>), dm.Method) as
1384                                 Func<StringComparison, StringComparison, bool>; 
1385                         Assert.IsTrue (d (0, 0));
1386                 }
1387
1388 #if !MONOTOUCH
1389                 public static void DynInvokeWithClosedFirstArg (object a, object b)
1390                 {
1391                 }
1392
1393                 [Test]
1394                 public void DynamicInvokeClosedOverNullDelegate () {
1395                         var dm = new DynamicMethod ("test", typeof (Delegate), null);
1396                         var il = dm.GetILGenerator ();
1397                         il.Emit (OpCodes.Ldnull);
1398                         il.Emit (OpCodes.Ldftn, GetType ().GetMethod ("DynInvokeWithClosedFirstArg"));
1399                         il.Emit (OpCodes.Newobj, typeof (Action<object>).GetConstructors ()[0]);
1400                         il.Emit (OpCodes.Ret);
1401
1402                         var f = (Func <object>) dm.CreateDelegate (typeof (Func <object>));
1403                         Action<object> ac = (Action<object>)f();
1404                         ac.DynamicInvoke (new object[] { "oi" });
1405                         ac.DynamicInvoke (new object[] { null });
1406                 }
1407
1408                 [Test]
1409                 public void DynamicInvokeFirstArgBoundDelegate () {
1410                         var dm = new DynamicMethod ("test", typeof (Delegate), null);
1411                         var il = dm.GetILGenerator ();
1412                         il.Emit (OpCodes.Ldstr, "test");
1413                         il.Emit (OpCodes.Ldftn, GetType ().GetMethod ("DynInvokeWithClosedFirstArg"));
1414                         il.Emit (OpCodes.Newobj, typeof (Action<object>).GetConstructors ()[0]);
1415                         il.Emit (OpCodes.Ret);
1416
1417                         var f = (Func <object>) dm.CreateDelegate (typeof (Func <object>));
1418                         Action<object> ac = (Action<object>)f();
1419                         ac.DynamicInvoke (new object[] { "oi" });
1420                         ac.DynamicInvoke (new object[] { null });
1421                 }
1422 #endif
1423
1424                 static bool Int32D2 (int x, int y)
1425                 {
1426                         return (x & y) == y; 
1427                 }
1428
1429                 public class B {
1430
1431                         public virtual string retarg3 (string s) {
1432                                 return s;
1433                         }
1434
1435                         static int Run (C x)
1436                         {
1437                                 return 5;
1438                         }
1439
1440                         public static void DoRun (C x)
1441                         {
1442                         }
1443
1444                         public static int StartRun (C x, B b)
1445                         {
1446                                 return 6;
1447                         }
1448
1449                         int Execute (C c)
1450                         {
1451                                 return 4;
1452                         }
1453
1454                         public void DoExecute (C c)
1455                         {
1456                         }
1457
1458                         public int StartExecute (C c, B b)
1459                         {
1460                                 return 3;
1461                         }
1462                 }
1463
1464                 public class C : B, Iface
1465                 {
1466                         public string retarg (string s) {
1467                                 return s;
1468                         }
1469
1470                         public string retarg2 (Iface iface, string s) {
1471                                 return s + "2";
1472                         }
1473
1474                         public override string retarg3 (string s) {
1475                                 return s + "2";
1476                         }
1477
1478                         static void Run (C x)
1479                         {
1480                         }
1481
1482                         public new static int DoRun (C x)
1483                         {
1484                                 return 107;
1485                         }
1486
1487                         void Execute (C c)
1488                         {
1489                         }
1490
1491                         public new int DoExecute (C c)
1492                         {
1493                                 return 102;
1494                         }
1495
1496                         public void M ()
1497                         {
1498                         }
1499
1500                         public void N (C c)
1501                         {
1502                         }
1503
1504                         public static void S (C c)
1505                         {
1506                         }
1507
1508                         private void PrivateInstance ()
1509                         {
1510                         }
1511                 }
1512
1513                 public delegate void D (C c);
1514                 public delegate int E (C c);
1515         }
1516 }