2009-02-21 Jb Evain <jbevain@novell.com>
[mono.git] / mcs / class / corlib / System / MonoType.cs
1 //
2 // System.MonoType
3 //
4 // Authors: 
5 //      Sean MacIsaac (macisaac@ximian.com)
6 //      Paolo Molaro (lupus@ximian.com)
7 //      Patrik Torstensson (patrik.torstensson@labs2.com)
8 //      Gonzalo Paniagua (gonzalo@ximian.com)
9 //
10 // (c) 2001-2003 Ximian, Inc.
11 // Copyright (C) 2003-2005 Novell, Inc (http://www.novell.com)
12 //
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
20 // 
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
23 // 
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 //
32
33 using System.Globalization;
34 using System.Reflection;
35 using System.Runtime.CompilerServices;
36 using System.Runtime.Serialization;
37 using System.Security;
38
39 namespace System
40 {
41         [Serializable]
42         internal class MonoType : Type, ISerializable
43         {
44
45                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
46                 private static extern void type_from_obj (MonoType type, Object obj);
47                 
48                 internal MonoType (Object obj)
49                 {
50                         // this should not be used - lupus
51                         type_from_obj (this, obj);
52                         
53                         throw new NotImplementedException ();
54                 }
55
56                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
57                 private static extern TypeAttributes get_attributes (Type type);
58         
59                 protected override TypeAttributes GetAttributeFlagsImpl ()
60                 {
61                         return get_attributes (this);
62                 }
63
64                 protected override ConstructorInfo GetConstructorImpl (BindingFlags bindingAttr,
65                                                                        Binder binder,
66                                                                        CallingConventions callConvention,
67                                                                        Type[] types,
68                                                                        ParameterModifier[] modifiers)
69                 {
70                         if (bindingAttr == BindingFlags.Default)
71                                 bindingAttr = BindingFlags.Public | BindingFlags.Instance;
72
73                         ConstructorInfo[] methods = GetConstructors (bindingAttr);
74                         ConstructorInfo found = null;
75                         MethodBase[] match;
76                         int count = 0;
77                         foreach (ConstructorInfo m in methods) {
78                                 // Under MS.NET, Standard|HasThis matches Standard...
79                                 if (callConvention != CallingConventions.Any && ((m.CallingConvention & callConvention) != callConvention))
80                                         continue;
81                                 found = m;
82                                 count++;
83                         }
84                         if (count == 0)
85                                 return null;
86                         if (types == null) {
87                                 if (count > 1)
88                                         throw new AmbiguousMatchException ();
89                                 return (ConstructorInfo) CheckMethodSecurity (found);
90                         }
91                         match = new MethodBase [count];
92                         if (count == 1)
93                                 match [0] = found;
94                         else {
95                                 count = 0;
96                                 foreach (ConstructorInfo m in methods) {
97                                         if (callConvention != CallingConventions.Any && ((m.CallingConvention & callConvention) != callConvention))
98                                                 continue;
99                                         match [count++] = m;
100                                 }
101                         }
102                         if (binder == null)
103                                 binder = Binder.DefaultBinder;
104                         return (ConstructorInfo) CheckMethodSecurity (binder.SelectMethod (bindingAttr, match, types, modifiers));
105                 }
106
107                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
108                 internal extern ConstructorInfo[] GetConstructors_internal (BindingFlags bindingAttr, Type reflected_type);
109
110                 public override ConstructorInfo[] GetConstructors (BindingFlags bindingAttr)
111                 {
112                         return GetConstructors_internal (bindingAttr, this);
113                 }
114
115                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
116                 extern EventInfo InternalGetEvent (string name, BindingFlags bindingAttr);
117
118                 public override EventInfo GetEvent (string name, BindingFlags bindingAttr)
119                 {
120                         if (name == null)
121                                 throw new ArgumentNullException ("name");
122
123                         return InternalGetEvent (name, bindingAttr);
124                 }
125
126                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
127                 internal extern EventInfo[] GetEvents_internal (BindingFlags bindingAttr, Type reflected_type);
128
129                 public override EventInfo[] GetEvents (BindingFlags bindingAttr)
130                 {
131                         return GetEvents_internal (bindingAttr, this);
132                 }
133
134                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
135                 public extern override FieldInfo GetField (string name, BindingFlags bindingAttr);
136
137                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
138                 internal extern FieldInfo[] GetFields_internal (BindingFlags bindingAttr, Type reflected_type);
139
140                 public override FieldInfo[] GetFields (BindingFlags bindingAttr)
141                 {
142                         return GetFields_internal (bindingAttr, this);
143                 }
144                 
145                 public override Type GetInterface (string name, bool ignoreCase)
146                 {
147                         if (name == null)
148                                 throw new ArgumentNullException ();
149
150                         Type[] interfaces = GetInterfaces();
151
152                         foreach (Type type in interfaces) {
153                                 if (String.Compare (type.Name, name, ignoreCase, CultureInfo.InvariantCulture) == 0)
154                                         return type;
155                                 if (String.Compare (type.FullName, name, ignoreCase, CultureInfo.InvariantCulture) == 0)
156                                         return type;
157                         }
158
159                         return null;
160                 }
161
162                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
163                 public extern override Type[] GetInterfaces();
164                 
165                 public override MemberInfo[] GetMembers( BindingFlags bindingAttr)
166                 {
167                         return FindMembers (MemberTypes.All, bindingAttr, null, null);
168                 }
169
170                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
171                 internal extern MethodInfo [] GetMethodsByName (string name, BindingFlags bindingAttr, bool ignoreCase, Type reflected_type);
172
173                 public override MethodInfo [] GetMethods (BindingFlags bindingAttr)
174                 {
175                         return GetMethodsByName (null, bindingAttr, false, this);
176                 }
177
178                 protected override MethodInfo GetMethodImpl (string name, BindingFlags bindingAttr,
179                                                              Binder binder,
180                                                              CallingConventions callConvention,
181                                                              Type[] types, ParameterModifier[] modifiers)
182                 {
183                         bool ignoreCase = ((bindingAttr & BindingFlags.IgnoreCase) != 0);
184                         MethodInfo[] methods = GetMethodsByName (name, bindingAttr, ignoreCase, this);
185                         MethodInfo found = null;
186                         MethodBase[] match;
187                         int count = 0;
188                         
189                         foreach (MethodInfo m in methods) {
190                                 // Under MS.NET, Standard|HasThis matches Standard...
191                                 if (callConvention != CallingConventions.Any && ((m.CallingConvention & callConvention) != callConvention))
192                                         continue;
193                                 found = m;
194                                 count++;
195                         }
196
197                         if (count == 0)
198                                 return null;
199                         
200                         if (count == 1 && types == null) 
201                                 return (MethodInfo) CheckMethodSecurity (found);
202
203                         match = new MethodBase [count];
204                         if (count == 1)
205                                 match [0] = found;
206                         else {
207                                 count = 0;
208                                 foreach (MethodInfo m in methods) {
209                                         if (callConvention != CallingConventions.Any && ((m.CallingConvention & callConvention) != callConvention))
210                                                 continue;
211                                         match [count++] = m;
212                                 }
213                         }
214
215                         if (types == null) 
216                                 return (MethodInfo) CheckMethodSecurity (Binder.FindMostDerivedMatch (match));
217
218                         if (binder == null)
219                                 binder = Binder.DefaultBinder;
220                         
221                         return (MethodInfo) CheckMethodSecurity (binder.SelectMethod (bindingAttr, match, types, modifiers));
222                 }
223
224                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
225                 extern MethodInfo GetCorrespondingInflatedMethod (MethodInfo generic);
226
227                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
228                 extern ConstructorInfo GetCorrespondingInflatedConstructor (ConstructorInfo generic);
229
230                 internal override MethodInfo GetMethod (MethodInfo fromNoninstanciated)
231                 {
232                         return GetCorrespondingInflatedMethod (fromNoninstanciated);
233                 }
234
235                 internal override ConstructorInfo GetConstructor (ConstructorInfo fromNoninstanciated)
236                 {
237                         return GetCorrespondingInflatedConstructor (fromNoninstanciated);
238                 }
239
240                 internal override FieldInfo GetField (FieldInfo fromNoninstanciated)
241                 {
242                         /* create sensible flags from given FieldInfo */
243                         BindingFlags flags = fromNoninstanciated.IsStatic ? BindingFlags.Static : BindingFlags.Instance;
244                         flags |= fromNoninstanciated.IsPublic ? BindingFlags.Public : BindingFlags.NonPublic;
245                         return GetField (fromNoninstanciated.Name, flags);
246                 }
247
248                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
249                 public extern override Type GetNestedType (string name, BindingFlags bindingAttr);
250
251                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
252                 public extern override Type[] GetNestedTypes (BindingFlags bindingAttr);
253
254                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
255                 internal extern PropertyInfo[] GetPropertiesByName (string name, BindingFlags bindingAttr, bool icase, Type reflected_type);
256
257                 public override PropertyInfo [] GetProperties (BindingFlags bindingAttr)
258                 {
259                         return GetPropertiesByName (null, bindingAttr, false, this);
260                 }
261
262                 protected override PropertyInfo GetPropertyImpl (string name, BindingFlags bindingAttr,
263                                                                  Binder binder, Type returnType,
264                                                                  Type[] types,
265                                                                  ParameterModifier[] modifiers)
266                 {
267                         bool ignoreCase = ((bindingAttr & BindingFlags.IgnoreCase) != 0);
268                         PropertyInfo [] props = GetPropertiesByName (name, bindingAttr, ignoreCase, this);
269                         int count = props.Length;
270                         if (count == 0)
271                                 return null;
272                         
273                         if (count == 1 && (types == null || types.Length == 0) && 
274                             (returnType == null || returnType == props[0].PropertyType))
275                                 return props [0];
276
277                         if (binder == null)
278                                 binder = Binder.DefaultBinder;
279
280                         return binder.SelectProperty (bindingAttr, props, returnType, types, modifiers);
281                 }
282
283                 protected override bool HasElementTypeImpl ()
284                 {
285                         return IsArrayImpl() || IsByRefImpl() || IsPointerImpl ();
286                 }
287
288                 protected override bool IsArrayImpl ()
289                 {
290                         return Type.IsArrayImpl (this);
291                 }
292
293                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
294                 protected extern override bool IsByRefImpl ();
295
296                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
297                 protected extern override bool IsCOMObjectImpl ();
298
299                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
300                 protected extern override bool IsPointerImpl ();
301
302                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
303                 protected extern override bool IsPrimitiveImpl ();
304
305                 public override bool IsSubclassOf (Type type)
306                 {
307                         if (type == null)
308                                 throw new ArgumentNullException ("type");
309
310                         return base.IsSubclassOf (type);
311                 }
312
313                 public override object InvokeMember (string name, BindingFlags invokeAttr,
314                                                      Binder binder, object target, object[] args,
315                                                      ParameterModifier[] modifiers,
316                                                      CultureInfo culture, string[] namedParameters)
317                 {
318 #if NET_2_0
319                         const string bindingflags_arg = "bindingFlags";
320 #else
321                         const string bindingflags_arg = "invokeAttr";
322 #endif
323
324
325                         if ((invokeAttr & BindingFlags.CreateInstance) != 0) {
326                                 if ((invokeAttr & (BindingFlags.GetField |
327                                                 BindingFlags.GetField | BindingFlags.GetProperty |
328                                                 BindingFlags.SetProperty)) != 0)
329                                         throw new ArgumentException (bindingflags_arg);
330                         } else if (name == null)
331                                 throw new ArgumentNullException ("name");
332                         if ((invokeAttr & BindingFlags.GetField) != 0 && (invokeAttr & BindingFlags.SetField) != 0)
333                                 throw new ArgumentException ("Cannot specify both Get and Set on a field.", bindingflags_arg);
334                         if ((invokeAttr & BindingFlags.GetProperty) != 0 && (invokeAttr & BindingFlags.SetProperty) != 0)
335                                 throw new ArgumentException ("Cannot specify both Get and Set on a property.", bindingflags_arg);
336                         if ((invokeAttr & BindingFlags.InvokeMethod) != 0) {
337                                 if ((invokeAttr & BindingFlags.SetField) != 0)
338                                         throw new ArgumentException ("Cannot specify Set on a field and Invoke on a method.", bindingflags_arg);
339                                 if ((invokeAttr & BindingFlags.SetProperty) != 0)
340                                         throw new ArgumentException ("Cannot specify Set on a property and Invoke on a method.", bindingflags_arg);
341                         }
342                         if ((namedParameters != null) && ((args == null) || args.Length < namedParameters.Length))
343                                 throw new ArgumentException ("namedParameters cannot be more than named arguments in number");
344                         if ((invokeAttr & (BindingFlags.InvokeMethod|BindingFlags.CreateInstance|BindingFlags.GetField|BindingFlags.SetField|BindingFlags.GetProperty|BindingFlags.SetProperty)) == 0)
345                                 throw new ArgumentException ("Must specify binding flags describing the invoke operation required.", bindingflags_arg);
346
347                         /* set some defaults if none are provided :-( */
348                         if ((invokeAttr & (BindingFlags.Public|BindingFlags.NonPublic)) == 0)
349                                 invokeAttr |= BindingFlags.Public;
350                         if ((invokeAttr & (BindingFlags.Static|BindingFlags.Instance)) == 0)
351                                 invokeAttr |= BindingFlags.Static|BindingFlags.Instance;
352
353                         if (binder == null)
354                                 binder = Binder.DefaultBinder;
355                         if ((invokeAttr & BindingFlags.CreateInstance) != 0) {
356                                 /* the name is ignored */
357                                 invokeAttr |= BindingFlags.DeclaredOnly;
358                                 ConstructorInfo[] ctors = GetConstructors (invokeAttr);
359                                 object state = null;
360                                 MethodBase ctor = binder.BindToMethod (invokeAttr, ctors, ref args, modifiers, culture, namedParameters, out state);
361                                 if (ctor == null) {
362                                         if (this.IsValueType && args == null)
363                                                 return Activator.CreateInstanceInternal (this);
364                                         
365                                         throw new MissingMethodException ("Constructor on type '" + FullName + "' not found.");
366                                 }
367                                 object result = ctor.Invoke (target, invokeAttr, binder, args, culture);
368                                 binder.ReorderArgumentArray (ref args, state);
369                                 return result;
370                         }
371                         if (name == String.Empty && Attribute.IsDefined (this, typeof (DefaultMemberAttribute))) {
372                                 DefaultMemberAttribute attr = (DefaultMemberAttribute) Attribute.GetCustomAttribute (this, typeof (DefaultMemberAttribute));
373                                 name = attr.MemberName;
374                         }
375                         bool ignoreCase = (invokeAttr & BindingFlags.IgnoreCase) != 0;
376                         string throwMissingMethodDescription = null;
377                         bool throwMissingFieldException = false;
378                         
379                         if ((invokeAttr & BindingFlags.InvokeMethod) != 0) {
380                                 MethodInfo[] methods = GetMethodsByName (name, invokeAttr, ignoreCase, this);
381                                 object state = null;
382                                 if (args == null)
383                                         args = new object [0];
384                                 MethodBase m = binder.BindToMethod (invokeAttr, methods, ref args, modifiers, culture, namedParameters, out state);
385                                 if (m == null) {
386                                         if (methods.Length > 0)
387                                                 throwMissingMethodDescription = "The best match for method " + name + " has some invalid parameter.";
388                                         else
389                                                 throwMissingMethodDescription = "Cannot find method " + name + ".";
390                                 } else {
391                                         ParameterInfo[] parameters = m.GetParameters();
392                                         for (int i = 0; i < parameters.Length; ++i) {
393                                                 if (System.Reflection.Missing.Value == args [i] && (parameters [i].Attributes & ParameterAttributes.HasDefault) != ParameterAttributes.HasDefault)
394                                                         throw new ArgumentException ("Used Missing.Value for argument without default value", "parameters");
395                                         }
396                                         bool hasParamArray = parameters.Length > 0 ? Attribute.IsDefined (parameters [parameters.Length - 1], 
397                                                 typeof (ParamArrayAttribute)) : false;
398                                         if (hasParamArray)
399                                                 ReorderParamArrayArguments (ref args, m);
400                                         object result = m.Invoke (target, invokeAttr, binder, args, culture);
401                                         binder.ReorderArgumentArray (ref args, state);
402                                         return result;
403                                 }
404                         }
405                         if ((invokeAttr & BindingFlags.GetField) != 0) {
406                                 FieldInfo f = GetField (name, invokeAttr);
407                                 if (f != null) {
408                                         return f.GetValue (target);
409                                 } else if ((invokeAttr & BindingFlags.GetProperty) == 0) {
410                                         throwMissingFieldException = true;
411                                 }
412                                 /* try GetProperty */
413                         } else if ((invokeAttr & BindingFlags.SetField) != 0) {
414                                 FieldInfo f = GetField (name, invokeAttr);
415                                 if (f != null) {
416 #if NET_2_0
417                                         if (args == null)
418                                                 throw new ArgumentNullException ("providedArgs");
419 #endif
420                                         if ((args == null) || args.Length != 1)
421                                                 throw new ArgumentException ("Only the field value can be specified to set a field value.", bindingflags_arg);
422                                         f.SetValue (target, args [0]);
423                                         return null;
424                                 } else if ((invokeAttr & BindingFlags.SetProperty) == 0) {
425                                         throwMissingFieldException = true;
426                                 }
427                                 /* try SetProperty */
428                         }
429                         if ((invokeAttr & BindingFlags.GetProperty) != 0) {
430                                 PropertyInfo[] properties = GetPropertiesByName (name, invokeAttr, ignoreCase, this);
431                                 object state = null;
432                                 int i, count = 0;
433                                 for (i = 0; i < properties.Length; ++i) {
434                                         if ((properties [i].GetGetMethod (true) != null))
435                                                 count++;
436                                 }
437                                 MethodBase[] smethods = new MethodBase [count];
438                                 count = 0;
439                                 for (i = 0; i < properties.Length; ++i) {
440                                         MethodBase mb = properties [i].GetGetMethod (true);
441                                         if (mb != null)
442                                                 smethods [count++] = mb;
443                                 }
444                                 MethodBase m = binder.BindToMethod (invokeAttr, smethods, ref args, modifiers, culture, namedParameters, out state);
445                                 if (m == null) {
446                                         throwMissingFieldException = true;
447                                 } else {
448                                         ParameterInfo[] parameters = m.GetParameters();
449                                         bool hasParamArray = parameters.Length > 0 ? Attribute.IsDefined (parameters [parameters.Length - 1], 
450                                                 typeof (ParamArrayAttribute)) : false;
451                                         if (hasParamArray)
452                                                 ReorderParamArrayArguments (ref args, m);
453                                         object result = m.Invoke (target, invokeAttr, binder, args, culture);
454                                         binder.ReorderArgumentArray (ref args, state);
455                                         return result;
456                                 }
457                         } else if ((invokeAttr & BindingFlags.SetProperty) != 0) {
458                                 PropertyInfo[] properties = GetPropertiesByName (name, invokeAttr, ignoreCase, this);
459                                 object state = null;
460                                 int i, count = 0;
461                                 for (i = 0; i < properties.Length; ++i) {
462                                         if (properties [i].GetSetMethod (true) != null)
463                                                 count++;
464                                 }
465                                 MethodBase[] smethods = new MethodBase [count];
466                                 count = 0;
467                                 for (i = 0; i < properties.Length; ++i) {
468                                         MethodBase mb = properties [i].GetSetMethod (true);
469                                         if (mb != null)
470                                                 smethods [count++] = mb;
471                                 }
472                                 MethodBase m = binder.BindToMethod (invokeAttr, smethods, ref args, modifiers, culture, namedParameters, out state);
473                                 if (m == null) {
474                                         throwMissingFieldException = true;
475                                 } else {
476                                         ParameterInfo[] parameters = m.GetParameters();
477                                         bool hasParamArray = parameters.Length > 0 ? Attribute.IsDefined (parameters [parameters.Length - 1], 
478                                                 typeof (ParamArrayAttribute)) : false;
479                                         if (hasParamArray)
480                                                 ReorderParamArrayArguments (ref args, m);
481                                         object result = m.Invoke (target, invokeAttr, binder, args, culture);
482                                         binder.ReorderArgumentArray (ref args, state);
483                                         return result;
484                                 }
485                         }
486                         if (throwMissingMethodDescription != null)
487                                 throw new MissingMethodException(throwMissingMethodDescription);
488                         if (throwMissingFieldException)
489                                 throw new MissingFieldException("Cannot find variable " + name + ".");
490
491                         return null;
492                 }
493
494                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
495                 public extern override Type GetElementType ();
496
497                 public override Type UnderlyingSystemType {
498                         get {
499                                 // This has _nothing_ to do with getting the base type of an enum etc.
500                                 return this;
501                         }
502                 }
503
504                 public extern override Assembly Assembly {
505                         [MethodImplAttribute(MethodImplOptions.InternalCall)]
506                         get;
507                 }
508
509                 public override string AssemblyQualifiedName {
510                         get {
511                                 return getFullName (true, true);
512                         }
513                 }
514
515                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
516                 private extern string getFullName(bool full_name, bool assembly_qualified);
517
518                 public extern override Type BaseType {
519                         [MethodImplAttribute(MethodImplOptions.InternalCall)]
520                         get;
521                 }
522
523                 public override string FullName {
524                         get {
525                                 return getFullName (true, false);
526                         }
527                 }
528
529                 public override Guid GUID {
530                         get {
531                                 object[] att = GetCustomAttributes(typeof(System.Runtime.InteropServices.GuidAttribute), true);
532                                 if (att.Length == 0)
533                                         return Guid.Empty;
534                                 return new Guid(((System.Runtime.InteropServices.GuidAttribute)att[0]).Value);
535                         }
536                 }
537
538                 public override bool IsDefined (Type attributeType, bool inherit)
539                 {
540                         return MonoCustomAttrs.IsDefined (this, attributeType, inherit);
541                 }
542
543                 public override object[] GetCustomAttributes (bool inherit)
544                 {
545                         return MonoCustomAttrs.GetCustomAttributes (this, inherit);
546                 }
547
548                 public override object[] GetCustomAttributes (Type attributeType, bool inherit)
549                 {
550                         if (attributeType == null)
551                         {
552                                 throw new ArgumentNullException("attributeType");
553                         }
554                         
555                         return MonoCustomAttrs.GetCustomAttributes (this, attributeType, inherit);
556                 }
557
558                 public override MemberTypes MemberType {
559                         get {
560                                 if (DeclaringType != null)
561                                         return MemberTypes.NestedType;
562                                 else
563                                         return MemberTypes.TypeInfo;
564                         }
565                 }
566
567                 public extern override string Name {
568                         [MethodImplAttribute(MethodImplOptions.InternalCall)]
569                         get;
570                 }
571
572                 public extern override string Namespace {
573                         [MethodImplAttribute(MethodImplOptions.InternalCall)]
574                         get;
575                 }
576
577                 public extern override Module Module {
578                         [MethodImplAttribute(MethodImplOptions.InternalCall)]
579                         get;
580                 }
581
582                 public extern override Type DeclaringType {
583                         [MethodImplAttribute(MethodImplOptions.InternalCall)]
584                         get;
585                 }
586
587                 public override Type ReflectedType {
588                         get {
589                                 return DeclaringType;
590                         }
591                 }
592
593                 public override RuntimeTypeHandle TypeHandle {
594                         get {
595                                 return _impl;
596                         }
597                 }
598
599                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
600                 public extern override int GetArrayRank ();
601
602                 public void GetObjectData(SerializationInfo info, StreamingContext context)
603                 {
604                         UnitySerializationHolder.GetTypeData (this, info, context);
605                 }
606
607                 public override string ToString()
608                 {
609                         return getFullName (false, false);
610                 }
611
612 #if NET_2_0 || BOOTSTRAP_NET_2_0
613                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
614                 public extern override Type [] GetGenericArguments ();
615
616                 public override bool ContainsGenericParameters {
617                         get {
618                                 if (IsGenericParameter)
619                                         return true;
620
621                                 if (IsGenericType) {
622                                         foreach (Type arg in GetGenericArguments ())
623                                                 if (arg.ContainsGenericParameters)
624                                                         return true;
625                                 }
626
627                                 if (HasElementType)
628                                         return GetElementType ().ContainsGenericParameters;
629
630                                 return false;
631                         }
632                 }
633
634                 public extern override bool IsGenericParameter {
635                         [MethodImplAttribute(MethodImplOptions.InternalCall)]
636                         get;
637                 }
638
639                 public extern override MethodBase DeclaringMethod {
640                         [MethodImplAttribute(MethodImplOptions.InternalCall)]
641                         get;
642                 }
643 #endif
644
645                 private MethodBase CheckMethodSecurity (MethodBase mb)
646                 {
647 #if NET_2_1
648                         return mb;
649 #else
650                         if (!SecurityManager.SecurityEnabled || (mb == null))
651                                 return mb;
652
653                         // Sadly we have no way to know which kind of security action this is
654                         // so we must do it the hard way. Actually this isn't so bad 
655                         // because we can skip the (mb.Attributes & MethodAttributes.HasSecurity)
656                         // icall required (and do it ourselves)
657
658                         // this (unlike the Invoke step) is _and stays_ a LinkDemand (caller)
659                         return SecurityManager.ReflectedLinkDemandQuery (mb) ? mb : null;
660 #endif
661                 }
662
663                 void ReorderParamArrayArguments(ref object[] args, MethodBase method)
664                 {
665                         ParameterInfo[] parameters = method.GetParameters();
666                         object[] newArgs = new object [parameters.Length];
667                         Array paramArray = Array.CreateInstance(parameters[parameters.Length - 1].ParameterType.GetElementType(), 
668                                 args.Length - (parameters.Length - 1));
669                         int paramArrayCount = 0;
670                         for (int i = 0; i < args.Length; i++) {
671                                 if (i < (parameters.Length - 1))
672                                         newArgs [i] = args [i];
673                                 else {
674                                         paramArray.SetValue (args [i], paramArrayCount);
675                                         paramArrayCount ++;
676                                 }
677                         }
678                         newArgs [parameters.Length - 1] = paramArray;
679                         args = newArgs;
680                 }
681         }
682 }