5 // Miguel de Icaza (miguel@ximian.com)
7 // (C) Ximian, Inc. http://www.ximian.com
9 // TODO: Mucho left to implement.
12 using System.Reflection;
13 using System.Collections;
14 using System.Runtime.CompilerServices;
15 using System.Globalization;
20 // FIXME: Implement the various IReflect dependencies
25 public abstract class Type : MemberInfo, IReflect {
27 internal RuntimeTypeHandle _impl;
29 public static readonly char Delimiter = '.';
30 public static readonly Type[] EmptyTypes = {};
31 public static readonly MemberFilter FilterAttribute = new MemberFilter (FilterAttribute_impl);
32 public static readonly MemberFilter FilterName = new MemberFilter (FilterName_impl);
33 public static readonly MemberFilter FilterNameIgnoreCase = new MemberFilter (FilterNameIgnoreCase_impl);
34 public static readonly object Missing;
36 private const BindingFlags DefaultBindingFlags =
37 BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance;
39 /* implementation of the delegates for MemberFilter */
40 static bool FilterName_impl (MemberInfo m, object filterCriteria)
42 string name = (string) filterCriteria;
43 return name.Equals (m.Name);
46 static bool FilterNameIgnoreCase_impl (MemberInfo m, object filterCriteria)
48 string name = (string) filterCriteria;
49 return String.Compare (name, m.Name, true) == 0;
53 static bool FilterAttribute_impl (MemberInfo m, object filterCriteria)
55 throw new NotImplementedException ("FilterAttribute_impl");
63 /// The assembly where the type is defined.
65 public abstract Assembly Assembly {
70 /// Gets the fully qualified name for the type including the
71 /// assembly name where the type is defined.
73 public abstract string AssemblyQualifiedName {
78 /// Returns the Attributes associated with the type.
80 public TypeAttributes Attributes {
82 return GetAttributeFlagsImpl ();
87 /// Returns the basetype for this type
89 public abstract Type BaseType {
94 /// Returns the class that declares the member.
96 public override Type DeclaringType {
105 public static Binder DefaultBinder {
107 return Binder.DefaultBinder;
112 /// The full name of the type including its namespace
114 public abstract string FullName {
118 public abstract Guid GUID {
122 public bool HasElementType {
124 return HasElementTypeImpl ();
128 public bool IsAbstract {
130 return (Attributes & TypeAttributes.Abstract) != 0;
134 public bool IsAnsiClass {
136 return (Attributes & TypeAttributes.StringFormatMask)
137 == TypeAttributes.AnsiClass;
141 public bool IsArray {
143 return IsArrayImpl ();
147 public bool IsAutoClass {
149 return (Attributes & TypeAttributes.StringFormatMask) == TypeAttributes.AutoClass;
153 public bool IsAutoLayout {
155 return (Attributes & TypeAttributes.LayoutMask) == TypeAttributes.AutoLayout;
159 public bool IsByRef {
161 return IsByRefImpl ();
165 public bool IsClass {
168 // This code used to probe for "this == typeof (System.Enum)", but in
169 // The .NET Framework 1.0, the above test return false
171 if (this == typeof (System.ValueType))
175 return !type_is_subtype_of (this, typeof (System.ValueType), false);
179 public bool IsCOMObject {
181 return IsCOMObjectImpl ();
185 public bool IsContextful {
187 return IsContextfulImpl ();
193 return type_is_subtype_of (this, typeof (System.Enum), false) &&
194 this != typeof (System.Enum);
198 public bool IsExplicitLayout {
200 return (Attributes & TypeAttributes.LayoutMask) == TypeAttributes.ExplicitLayout;
204 public bool IsImport {
206 return (Attributes & TypeAttributes.Import) != 0;
210 public bool IsInterface {
212 return (Attributes & TypeAttributes.ClassSemanticsMask) == TypeAttributes.Interface;
216 public bool IsLayoutSequential {
218 return (Attributes & TypeAttributes.LayoutMask) == TypeAttributes.SequentialLayout;
222 public bool IsMarshalByRef {
224 return IsMarshalByRefImpl ();
228 public bool IsNestedAssembly {
230 return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedAssembly;
234 public bool IsNestedFamANDAssem {
236 return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamANDAssem;
240 public bool IsNestedFamily {
242 return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamily;
246 public bool IsNestedFamORAssem {
248 return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamORAssem;
252 public bool IsNestedPrivate {
254 return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPrivate;
258 public bool IsNestedPublic {
260 return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPublic;
264 public bool IsNotPublic {
270 public bool IsPointer {
272 return IsPointerImpl ();
276 public bool IsPrimitive {
278 return IsPrimitiveImpl ();
282 public bool IsPublic {
284 return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.Public;
288 public bool IsSealed {
290 return (Attributes & TypeAttributes.Sealed) != 0;
294 public bool IsSerializable {
296 // Enums and delegates are always serializable
297 return (Attributes & TypeAttributes.Serializable) != 0 || IsEnum ||
298 type_is_subtype_of (this, typeof (System.Delegate), false);
302 public bool IsSpecialName {
304 return (Attributes & TypeAttributes.SpecialName) != 0;
308 public bool IsUnicodeClass {
310 return (Attributes & TypeAttributes.StringFormatMask) == TypeAttributes.UnicodeClass;
314 public bool IsValueType {
316 return IsValueTypeImpl ();
320 public override MemberTypes MemberType {
321 get {return MemberTypes.TypeInfo;}
324 public abstract Module Module {get;}
326 public abstract string Namespace {get;}
328 public override Type ReflectedType {
334 public abstract RuntimeTypeHandle TypeHandle {get;}
336 public ConstructorInfo TypeInitializer {
338 return GetConstructorImpl (
339 BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static,
341 CallingConventions.Any,
347 public abstract Type UnderlyingSystemType {get;}
349 public override bool Equals (object o)
354 // TODO: return UnderlyingSystemType == o.UnderlyingSystemType;
355 Type cmp = o as Type;
361 [MethodImplAttribute(MethodImplOptions.InternalCall)]
362 public extern bool Equals (Type type);
364 [MethodImplAttribute(MethodImplOptions.InternalCall)]
365 private static extern Type internal_from_handle (IntPtr handle);
367 [MethodImplAttribute(MethodImplOptions.InternalCall)]
368 private static extern Type internal_from_name (string name, bool throwOnError, bool ignoreCase);
370 public static Type GetType(string typeName)
372 if (typeName == null)
373 throw new ArgumentNullException ("typeName");
375 return internal_from_name (typeName, false, false);
378 public static Type GetType(string typeName, bool throwOnError)
380 if (typeName == null)
381 throw new ArgumentNullException ("typeName");
383 Type type = internal_from_name (typeName, throwOnError, false);
384 if (throwOnError && type == null)
385 throw new TypeLoadException ("Error loading '" + typeName + "'");
390 public static Type GetType(string typeName, bool throwOnError, bool ignoreCase)
392 if (typeName == null)
393 throw new ArgumentNullException ("typeName");
395 Type t = internal_from_name (typeName, throwOnError, ignoreCase);
396 if (throwOnError && t == null)
397 throw new TypeLoadException ("Error loading '" + typeName + "'");
402 public static Type[] GetTypeArray (object[] args) {
404 throw new ArgumentNullException ("args");
407 ret = new Type [args.Length];
408 for (int i = 0; i < args.Length; ++i)
409 ret [i] = args[i].GetType ();
413 [MethodImplAttribute(MethodImplOptions.InternalCall)]
414 public extern static TypeCode GetTypeCode (Type type);
417 public static Type GetTypeFromCLSID (Guid clsid)
419 throw new NotImplementedException ();
423 public static Type GetTypeFromCLSID (Guid clsid, bool throwOnError)
425 throw new NotImplementedException ();
429 public static Type GetTypeFromCLSID (Guid clsid, string server)
431 throw new NotImplementedException ();
435 public static Type GetTypeFromCLSID (Guid clsid, string server, bool throwOnError)
437 throw new NotImplementedException ();
440 public static Type GetTypeFromHandle (RuntimeTypeHandle handle)
442 return internal_from_handle (handle.Value);
446 public static Type GetTypeFromProgID (string progID)
448 throw new NotImplementedException ();
452 public static Type GetTypeFromProgID (string progID, bool throwOnError)
454 throw new NotImplementedException ();
458 public static Type GetTypeFromProgID (string progID, string server)
460 throw new NotImplementedException ();
464 public static Type GetTypeFromProgID (string progID, string server, bool throwOnError)
466 throw new NotImplementedException ();
469 public static RuntimeTypeHandle GetTypeHandle (object o)
471 return o.GetType().TypeHandle;
474 [MethodImplAttribute(MethodImplOptions.InternalCall)]
475 internal static extern bool type_is_subtype_of (Type a, Type b, bool check_interfaces);
477 [MethodImplAttribute(MethodImplOptions.InternalCall)]
478 internal static extern bool type_is_assignable_from (Type a, Type b);
480 public virtual bool IsSubclassOf (Type c)
485 return (this != c) && type_is_subtype_of (this, c, false);
488 public virtual Type[] FindInterfaces (TypeFilter filter, object filterCriteria)
491 throw new ArgumentNullException ("filter");
493 ArrayList ifaces = new ArrayList ();
494 foreach (Type iface in GetInterfaces ()) {
495 if (filter (iface, filterCriteria))
499 return (Type []) ifaces.ToArray (typeof (Type));
502 public Type GetInterface (string name) {
503 return GetInterface (name, false);
506 public abstract Type GetInterface (string name, bool ignoreCase);
508 [MethodImplAttribute(MethodImplOptions.InternalCall)]
509 internal static extern void GetInterfaceMapData (Type t, Type iface, out MethodInfo[] targets, out MethodInfo[] methods);
511 public virtual InterfaceMapping GetInterfaceMap (Type interfaceType) {
512 InterfaceMapping res;
513 if (interfaceType == null)
514 throw new ArgumentNullException ("interfaceType");
515 if (!interfaceType.IsInterface)
516 throw new ArgumentException ("type argument must be an interface", "interfaceType");
517 res.TargetType = this;
518 res.InterfaceType = interfaceType;
519 GetInterfaceMapData (this, interfaceType, out res.TargetMethods, out res.InterfaceMethods);
520 if (res.TargetMethods == null)
521 throw new ArgumentException ("interface not found", "interfaceType");
526 public abstract Type[] GetInterfaces ();
528 public virtual bool IsAssignableFrom (Type c)
536 return type_is_assignable_from (this, c);
539 public virtual bool IsInstanceOfType (object o) {
541 return IsAssignableFrom (o.GetType ());
546 public virtual int GetArrayRank ()
548 throw new NotSupportedException (); // according to MSDN
551 public abstract Type GetElementType ();
553 public EventInfo GetEvent (string name)
555 return GetEvent (name, DefaultBindingFlags);
558 public abstract EventInfo GetEvent (string name, BindingFlags bindingAttr);
560 public virtual EventInfo[] GetEvents ()
562 return GetEvents (DefaultBindingFlags);
565 public abstract EventInfo[] GetEvents (BindingFlags bindingAttr);
567 public FieldInfo GetField( string name)
569 return GetField (name, DefaultBindingFlags);
572 public abstract FieldInfo GetField( string name, BindingFlags bindingAttr);
574 public FieldInfo[] GetFields ()
576 return GetFields (DefaultBindingFlags);
579 public abstract FieldInfo[] GetFields (BindingFlags bindingAttr);
581 public override int GetHashCode()
583 return (int)_impl.Value;
586 public MemberInfo[] GetMember( string name)
588 return GetMember (name, DefaultBindingFlags);
591 public virtual MemberInfo[] GetMember( string name, BindingFlags bindingAttr)
593 return GetMember (name, MemberTypes.All, bindingAttr);
596 public virtual MemberInfo[] GetMember (string name, MemberTypes type,
597 BindingFlags bindingAttr)
599 return FindMembers (type, bindingAttr, FilterName, name);
602 public MemberInfo[] GetMembers()
604 return GetMembers (DefaultBindingFlags);
607 public abstract MemberInfo[] GetMembers (BindingFlags bindingAttr);
609 public MethodInfo GetMethod (string name)
612 throw new ArgumentNullException ("name");
613 return GetMethodImpl (name, DefaultBindingFlags, null, CallingConventions.Any, null, null);
616 public MethodInfo GetMethod (string name, BindingFlags bindingAttr)
619 throw new ArgumentNullException ("name");
621 return GetMethodImpl (name, bindingAttr, null, CallingConventions.Any, null, null);
624 public MethodInfo GetMethod (string name, Type[] types)
626 return GetMethod (name, DefaultBindingFlags, null, CallingConventions.Any, types, null);
629 public MethodInfo GetMethod( string name, Type[] types, ParameterModifier[] modifiers)
631 return GetMethod (name, DefaultBindingFlags, null,
632 CallingConventions.Any, types, modifiers);
635 public MethodInfo GetMethod (string name, BindingFlags bindingAttr, Binder binder,
636 Type[] types, ParameterModifier[] modifiers)
639 return GetMethod (name, bindingAttr, binder,
640 CallingConventions.Any, types, modifiers);
643 public MethodInfo GetMethod (string name, BindingFlags bindingAttr,
644 Binder binder, CallingConventions callConvention,
645 Type[] types, ParameterModifier[] modifiers)
648 throw new ArgumentNullException ("name");
650 throw new ArgumentNullException ("types");
652 return GetMethodImpl (name, bindingAttr, binder, callConvention, types, modifiers);
655 protected abstract MethodInfo GetMethodImpl (string name, BindingFlags bindingAttr,
657 CallingConventions callConvention,
658 Type[] types, ParameterModifier[] modifiers);
660 public MethodInfo[] GetMethods ()
662 return GetMethods (DefaultBindingFlags);
665 public abstract MethodInfo[] GetMethods (BindingFlags bindingAttr);
667 public Type GetNestedType (string name)
669 return GetNestedType (name, DefaultBindingFlags);
672 public abstract Type GetNestedType (string name, BindingFlags bindingAttr);
674 public Type[] GetNestedTypes ()
676 return GetNestedTypes (DefaultBindingFlags);
679 public abstract Type[] GetNestedTypes (BindingFlags bindingAttr);
682 public PropertyInfo[] GetProperties ()
684 return GetProperties (DefaultBindingFlags);
687 public abstract PropertyInfo[] GetProperties (BindingFlags bindingAttr);
690 public PropertyInfo GetProperty (string name)
693 throw new ArgumentNullException ("name");
695 return GetPropertyImpl (name, DefaultBindingFlags, null, null, new Type[0], null);
698 public PropertyInfo GetProperty (string name, BindingFlags bindingAttr)
701 throw new ArgumentNullException ("name");
702 return GetPropertyImpl (name, bindingAttr, null, null, new Type[0], null);
705 public PropertyInfo GetProperty (string name, Type returnType)
708 throw new ArgumentNullException ("name");
709 return GetPropertyImpl (name, DefaultBindingFlags, null, returnType, new Type[0], null);
712 public PropertyInfo GetProperty (string name, Type[] types)
714 return GetProperty (name, DefaultBindingFlags, null, null, types, null);
717 public PropertyInfo GetProperty (string name, Type returnType, Type[] types)
719 return GetProperty (name, DefaultBindingFlags, null, returnType, types, null);
722 public PropertyInfo GetProperty( string name, Type returnType, Type[] types,
723 ParameterModifier[] modifiers)
725 return GetProperty (name, DefaultBindingFlags, null, returnType, types, modifiers);
728 public PropertyInfo GetProperty (string name, BindingFlags bindingAttr,
729 Binder binder, Type returnType,
730 Type[] types, ParameterModifier[] modifiers)
733 throw new ArgumentNullException ("name");
735 throw new ArgumentNullException ("types");
737 return GetPropertyImpl (name, bindingAttr, binder, returnType, types, modifiers);
740 protected abstract PropertyInfo GetPropertyImpl (string name,
741 BindingFlags bindingAttr,
742 Binder binder, Type returnType,
744 ParameterModifier[] modifiers);
746 protected abstract ConstructorInfo GetConstructorImpl (BindingFlags bindingAttr,
748 CallingConventions callConvention,
750 ParameterModifier[] modifiers);
752 protected abstract TypeAttributes GetAttributeFlagsImpl ();
753 protected abstract bool HasElementTypeImpl ();
754 protected abstract bool IsArrayImpl ();
755 protected abstract bool IsByRefImpl ();
756 protected abstract bool IsCOMObjectImpl ();
757 protected abstract bool IsPointerImpl ();
758 protected abstract bool IsPrimitiveImpl ();
760 [MethodImplAttribute(MethodImplOptions.InternalCall)]
761 internal static extern bool IsArrayImpl (Type type);
763 protected virtual bool IsValueTypeImpl ()
765 if (this == typeof (Enum) || this == typeof (ValueType))
768 return IsSubclassOf (typeof (ValueType));
771 protected virtual bool IsContextfulImpl ()
773 return typeof (ContextBoundObject).IsAssignableFrom (this);
776 protected virtual bool IsMarshalByRefImpl ()
778 return typeof (MarshalByRefObject).IsAssignableFrom (this);
781 public ConstructorInfo GetConstructor (Type[] types)
783 return GetConstructorImpl (
784 DefaultBindingFlags, null, CallingConventions.Any, types, null);
787 public ConstructorInfo GetConstructor (BindingFlags bindingAttr, Binder binder,
788 Type[] types, ParameterModifier[] modifiers)
790 return GetConstructorImpl (
791 bindingAttr, binder, CallingConventions.Any, types, modifiers);
794 public ConstructorInfo GetConstructor (BindingFlags bindingAttr, Binder binder,
795 CallingConventions callConvention,
796 Type[] types, ParameterModifier[] modifiers)
799 throw new ArgumentNullException ("types");
801 return GetConstructorImpl (bindingAttr, binder, callConvention, types, modifiers);
804 public ConstructorInfo[] GetConstructors ()
806 return GetConstructors (BindingFlags.Public | BindingFlags.Instance);
809 public abstract ConstructorInfo[] GetConstructors (BindingFlags bindingAttr);
811 public virtual MemberInfo[] GetDefaultMembers ()
813 object [] att = GetCustomAttributes (typeof (DefaultMemberAttribute), true);
815 return new MemberInfo [0];
817 MemberInfo [] member = GetMember (((DefaultMemberAttribute) att [0]).MemberName);
818 return (member != null) ? member : new MemberInfo [0];
821 public virtual MemberInfo[] FindMembers (MemberTypes memberType, BindingFlags bindingAttr,
822 MemberFilter filter, object filterCriteria)
825 ArrayList l = new ArrayList ();
827 // Console.WriteLine ("FindMembers for {0} (Type: {1}): {2}",
828 // this.FullName, this.GetType().FullName, this.obj_address());
830 if ((memberType & MemberTypes.Constructor) != 0) {
831 ConstructorInfo[] c = GetConstructors (bindingAttr);
832 if (filter != null) {
833 foreach (MemberInfo m in c) {
834 if (filter (m, filterCriteria))
841 if ((memberType & MemberTypes.Event) != 0) {
842 EventInfo[] c = GetEvents (bindingAttr);
843 if (filter != null) {
844 foreach (MemberInfo m in c) {
845 if (filter (m, filterCriteria))
852 if ((memberType & MemberTypes.Field) != 0) {
853 FieldInfo[] c = GetFields (bindingAttr);
854 if (filter != null) {
855 foreach (MemberInfo m in c) {
856 if (filter (m, filterCriteria))
863 if ((memberType & MemberTypes.Method) != 0) {
864 MethodInfo[] c = GetMethods (bindingAttr);
865 if (filter != null) {
866 foreach (MemberInfo m in c) {
867 if (filter (m, filterCriteria))
874 if ((memberType & MemberTypes.Property) != 0) {
878 if (filter != null) {
880 while ((l.Count == count) && (ptype != null)) {
881 c = ptype.GetProperties (bindingAttr);
882 foreach (MemberInfo m in c) {
883 if (filter (m, filterCriteria))
886 ptype = ptype.BaseType;
889 c = GetProperties (bindingAttr);
893 if ((memberType & MemberTypes.NestedType) != 0) {
894 Type[] c = GetNestedTypes (bindingAttr);
895 if (filter != null) {
896 foreach (MemberInfo m in c) {
897 if (filter (m, filterCriteria)) {
905 result = new MemberInfo [l.Count];
910 public object InvokeMember (string name, BindingFlags invokeAttr, Binder binder,
911 object target, object[] args)
913 return InvokeMember (name, invokeAttr, binder, target, args, null, null, null);
916 public object InvokeMember (string name, BindingFlags invokeAttr, Binder binder,
917 object target, object[] args, CultureInfo culture)
919 return InvokeMember (name, invokeAttr, binder, target, args, null, culture, null);
922 public abstract object InvokeMember (string name, BindingFlags invokeAttr,
923 Binder binder, object target, object[] args,
924 ParameterModifier[] modifiers,
925 CultureInfo culture, string[] namedParameters);
927 public override string ToString()
933 [MethodImplAttribute(MethodImplOptions.InternalCall)]
934 public extern Type [] GetGenericParameters ();
936 public abstract bool HasGenericParameters {
940 public abstract bool HasUnboundGenericParameters {
944 [MethodImplAttribute(MethodImplOptions.InternalCall)]
945 static extern Type GetGenericTypeDefinition (Type t);
947 public virtual Type GetGenericTypeDefinition ()
949 Type res = GetGenericTypeDefinition (this);
951 throw new ArgumentException ();
955 public extern bool IsGenericInstance {
956 [MethodImplAttribute(MethodImplOptions.InternalCall)]
960 [MethodImplAttribute(MethodImplOptions.InternalCall)]
961 static extern Type BindGenericParameters (Type gt, Type [] types);
963 public Type BindGenericParameters (Type [] types)
966 throw new ArgumentNullException ("types");
967 foreach (Type t in types) {
969 throw new ArgumentNullException ("types");
971 Type res = BindGenericParameters (this, types);
973 throw new TypeLoadException ();
977 public abstract bool IsUnboundGenericParameter {
981 [MethodImplAttribute(MethodImplOptions.InternalCall)]
982 extern int GetGenericParameterPosition ();
984 public virtual int GenericParameterPosition {
986 int res = GetGenericParameterPosition ();
988 throw new ArgumentException ();