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