1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
5 using System.Threading;
6 using System.Reflection;
7 using System.Diagnostics;
8 using System.Globalization;
9 using System.Runtime.InteropServices;
13 public abstract partial class Type : MemberInfo, IReflect
17 public override MemberTypes MemberType => MemberTypes.TypeInfo;
19 public new Type GetType() => base.GetType();
21 public abstract string Namespace { get; }
22 public abstract string AssemblyQualifiedName { get; }
23 public abstract string FullName { get; }
25 public abstract Assembly Assembly { get; }
26 public abstract new Module Module { get; }
28 public bool IsNested => DeclaringType != null;
29 public override Type DeclaringType => null;
30 public virtual MethodBase DeclaringMethod => null;
32 public override Type ReflectedType => null;
33 public abstract Type UnderlyingSystemType { get; }
35 public virtual bool IsTypeDefinition { get { throw NotImplemented.ByDesign; } }
36 public bool IsArray => IsArrayImpl();
37 protected abstract bool IsArrayImpl();
38 public bool IsByRef => IsByRefImpl();
39 protected abstract bool IsByRefImpl();
40 public bool IsPointer => IsPointerImpl();
41 protected abstract bool IsPointerImpl();
42 public virtual bool IsConstructedGenericType { get { throw NotImplemented.ByDesign; } }
43 public virtual bool IsGenericParameter => false;
44 public virtual bool IsGenericTypeParameter => IsGenericParameter && DeclaringMethod == null;
45 public virtual bool IsGenericMethodParameter => IsGenericParameter && DeclaringMethod != null;
46 public virtual bool IsGenericType => false;
47 public virtual bool IsGenericTypeDefinition => false;
49 public virtual bool IsSZArray { get { throw NotImplemented.ByDesign; } }
50 public virtual bool IsVariableBoundArray => IsArray && !IsSZArray;
52 public virtual bool IsByRefLike => throw new NotSupportedException(SR.NotSupported_SubclassOverride);
54 public bool HasElementType => HasElementTypeImpl();
55 protected abstract bool HasElementTypeImpl();
56 public abstract Type GetElementType();
58 public virtual int GetArrayRank() { throw new NotSupportedException(SR.NotSupported_SubclassOverride); }
60 public virtual Type GetGenericTypeDefinition() { throw new NotSupportedException(SR.NotSupported_SubclassOverride); }
61 public virtual Type[] GenericTypeArguments => (IsGenericType && !IsGenericTypeDefinition) ? GetGenericArguments() : Array.Empty<Type>();
62 public virtual Type[] GetGenericArguments() { throw new NotSupportedException(SR.NotSupported_SubclassOverride); }
64 public virtual int GenericParameterPosition { get { throw new InvalidOperationException(SR.Arg_NotGenericParameter); } }
65 public virtual GenericParameterAttributes GenericParameterAttributes { get { throw new NotSupportedException(); } }
66 public virtual Type[] GetGenericParameterConstraints()
68 if (!IsGenericParameter)
69 throw new InvalidOperationException(SR.Arg_NotGenericParameter);
70 throw new InvalidOperationException();
73 public TypeAttributes Attributes => GetAttributeFlagsImpl();
74 protected abstract TypeAttributes GetAttributeFlagsImpl();
76 public bool IsAbstract => (GetAttributeFlagsImpl() & TypeAttributes.Abstract) != 0;
77 public bool IsImport => (GetAttributeFlagsImpl() & TypeAttributes.Import) != 0;
78 public bool IsSealed => (GetAttributeFlagsImpl() & TypeAttributes.Sealed) != 0;
79 public bool IsSpecialName => (GetAttributeFlagsImpl() & TypeAttributes.SpecialName) != 0;
81 public bool IsClass => (GetAttributeFlagsImpl() & TypeAttributes.ClassSemanticsMask) == TypeAttributes.Class && !IsValueType;
83 public bool IsNestedAssembly => (GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedAssembly;
84 public bool IsNestedFamANDAssem => (GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamANDAssem;
85 public bool IsNestedFamily => (GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamily;
86 public bool IsNestedFamORAssem => (GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamORAssem;
87 public bool IsNestedPrivate => (GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPrivate;
88 public bool IsNestedPublic => (GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPublic;
89 public bool IsNotPublic => (GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NotPublic;
90 public bool IsPublic => (GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.Public;
92 public bool IsAutoLayout => (GetAttributeFlagsImpl() & TypeAttributes.LayoutMask) == TypeAttributes.AutoLayout;
93 public bool IsExplicitLayout => (GetAttributeFlagsImpl() & TypeAttributes.LayoutMask) == TypeAttributes.ExplicitLayout;
94 public bool IsLayoutSequential => (GetAttributeFlagsImpl() & TypeAttributes.LayoutMask) == TypeAttributes.SequentialLayout;
96 public bool IsAnsiClass => (GetAttributeFlagsImpl() & TypeAttributes.StringFormatMask) == TypeAttributes.AnsiClass;
97 public bool IsAutoClass => (GetAttributeFlagsImpl() & TypeAttributes.StringFormatMask) == TypeAttributes.AutoClass;
98 public bool IsUnicodeClass => (GetAttributeFlagsImpl() & TypeAttributes.StringFormatMask) == TypeAttributes.UnicodeClass;
100 public bool IsCOMObject => IsCOMObjectImpl();
101 protected abstract bool IsCOMObjectImpl();
102 public bool IsContextful => IsContextfulImpl();
103 protected virtual bool IsContextfulImpl() => false;
105 public virtual bool IsCollectible => true;
107 public virtual bool IsEnum => IsSubclassOf(typeof(Enum));
108 public bool IsMarshalByRef => IsMarshalByRefImpl();
109 protected virtual bool IsMarshalByRefImpl() => false;
110 public bool IsPrimitive => IsPrimitiveImpl();
111 protected abstract bool IsPrimitiveImpl();
112 public bool IsValueType => IsValueTypeImpl();
113 protected virtual bool IsValueTypeImpl() => IsSubclassOf(typeof(ValueType));
115 public virtual bool IsSignatureType => false;
117 public virtual bool IsSecurityCritical { get { throw NotImplemented.ByDesign; } }
118 public virtual bool IsSecuritySafeCritical { get { throw NotImplemented.ByDesign; } }
119 public virtual bool IsSecurityTransparent { get { throw NotImplemented.ByDesign; } }
121 public virtual StructLayoutAttribute StructLayoutAttribute { get { throw new NotSupportedException(); } }
122 public ConstructorInfo TypeInitializer => GetConstructorImpl(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, CallingConventions.Any, Type.EmptyTypes, null);
124 public ConstructorInfo GetConstructor(Type[] types) => GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, types, null);
125 public ConstructorInfo GetConstructor(BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers) => GetConstructor(bindingAttr, binder, CallingConventions.Any, types, modifiers);
126 public ConstructorInfo GetConstructor(BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
129 throw new ArgumentNullException(nameof(types));
130 for (int i = 0; i < types.Length; i++)
132 if (types[i] == null)
133 throw new ArgumentNullException(nameof(types));
135 return GetConstructorImpl(bindingAttr, binder, callConvention, types, modifiers);
137 protected abstract ConstructorInfo GetConstructorImpl(BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers);
139 public ConstructorInfo[] GetConstructors() => GetConstructors(BindingFlags.Public | BindingFlags.Instance);
140 public abstract ConstructorInfo[] GetConstructors(BindingFlags bindingAttr);
142 public EventInfo GetEvent(string name) => GetEvent(name, Type.DefaultLookup);
143 public abstract EventInfo GetEvent(string name, BindingFlags bindingAttr);
145 public virtual EventInfo[] GetEvents() => GetEvents(Type.DefaultLookup);
146 public abstract EventInfo[] GetEvents(BindingFlags bindingAttr);
148 public FieldInfo GetField(string name) => GetField(name, Type.DefaultLookup);
149 public abstract FieldInfo GetField(string name, BindingFlags bindingAttr);
151 public FieldInfo[] GetFields() => GetFields(Type.DefaultLookup);
152 public abstract FieldInfo[] GetFields(BindingFlags bindingAttr);
154 public MemberInfo[] GetMember(string name) => GetMember(name, Type.DefaultLookup);
155 public virtual MemberInfo[] GetMember(string name, BindingFlags bindingAttr) => GetMember(name, MemberTypes.All, bindingAttr);
156 public virtual MemberInfo[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr) { throw new NotSupportedException(SR.NotSupported_SubclassOverride); }
158 public MemberInfo[] GetMembers() => GetMembers(Type.DefaultLookup);
159 public abstract MemberInfo[] GetMembers(BindingFlags bindingAttr);
161 public MethodInfo GetMethod(string name) => GetMethod(name, Type.DefaultLookup);
162 public MethodInfo GetMethod(string name, BindingFlags bindingAttr)
165 throw new ArgumentNullException(nameof(name));
166 return GetMethodImpl(name, bindingAttr, null, CallingConventions.Any, null, null);
169 public MethodInfo GetMethod(string name, Type[] types) => GetMethod(name, types, null);
170 public MethodInfo GetMethod(string name, Type[] types, ParameterModifier[] modifiers) => GetMethod(name, Type.DefaultLookup, null, types, modifiers);
171 public MethodInfo GetMethod(string name, BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers) => GetMethod(name, bindingAttr, binder, CallingConventions.Any, types, modifiers);
172 public MethodInfo GetMethod(string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
175 throw new ArgumentNullException(nameof(name));
177 throw new ArgumentNullException(nameof(types));
178 for (int i = 0; i < types.Length; i++)
180 if (types[i] == null)
181 throw new ArgumentNullException(nameof(types));
183 return GetMethodImpl(name, bindingAttr, binder, callConvention, types, modifiers);
186 protected abstract MethodInfo GetMethodImpl(string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers);
188 public MethodInfo GetMethod(string name, int genericParameterCount, Type[] types) => GetMethod(name, genericParameterCount, types, null);
189 public MethodInfo GetMethod(string name, int genericParameterCount, Type[] types, ParameterModifier[] modifiers) => GetMethod(name, genericParameterCount, Type.DefaultLookup, null, types, modifiers);
190 public MethodInfo GetMethod(string name, int genericParameterCount, BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers) => GetMethod(name, genericParameterCount, bindingAttr, binder, CallingConventions.Any, types, modifiers);
191 public MethodInfo GetMethod(string name, int genericParameterCount, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
194 throw new ArgumentNullException(nameof(name));
195 if (genericParameterCount < 0)
196 throw new ArgumentException(SR.ArgumentOutOfRange_NeedNonNegNum, nameof(genericParameterCount));
198 throw new ArgumentNullException(nameof(types));
199 for (int i = 0; i < types.Length; i++)
201 if (types[i] == null)
202 throw new ArgumentNullException(nameof(types));
204 return GetMethodImpl(name, genericParameterCount, bindingAttr, binder, callConvention, types, modifiers);
207 protected virtual MethodInfo GetMethodImpl(string name, int genericParameterCount, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers) => throw new NotSupportedException();
209 public MethodInfo[] GetMethods() => GetMethods(Type.DefaultLookup);
210 public abstract MethodInfo[] GetMethods(BindingFlags bindingAttr);
212 public Type GetNestedType(string name) => GetNestedType(name, Type.DefaultLookup);
213 public abstract Type GetNestedType(string name, BindingFlags bindingAttr);
215 public Type[] GetNestedTypes() => GetNestedTypes(Type.DefaultLookup);
216 public abstract Type[] GetNestedTypes(BindingFlags bindingAttr);
218 public PropertyInfo GetProperty(string name) => GetProperty(name, Type.DefaultLookup);
219 public PropertyInfo GetProperty(string name, BindingFlags bindingAttr)
222 throw new ArgumentNullException(nameof(name));
223 return GetPropertyImpl(name, bindingAttr, null, null, null, null);
226 public PropertyInfo GetProperty(string name, Type returnType)
229 throw new ArgumentNullException(nameof(name));
230 if (returnType == null)
231 throw new ArgumentNullException(nameof(returnType));
232 return GetPropertyImpl(name, Type.DefaultLookup, null, returnType, null, null);
235 public PropertyInfo GetProperty(string name, Type[] types) => GetProperty(name, null, types);
236 public PropertyInfo GetProperty(string name, Type returnType, Type[] types) => GetProperty(name, returnType, types, null);
237 public PropertyInfo GetProperty(string name, Type returnType, Type[] types, ParameterModifier[] modifiers) => GetProperty(name, Type.DefaultLookup, null, returnType, types, modifiers);
238 public PropertyInfo GetProperty(string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers)
241 throw new ArgumentNullException(nameof(name));
243 throw new ArgumentNullException(nameof(types));
244 return GetPropertyImpl(name, bindingAttr, binder, returnType, types, modifiers);
247 protected abstract PropertyInfo GetPropertyImpl(string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers);
249 public PropertyInfo[] GetProperties() => GetProperties(Type.DefaultLookup);
250 public abstract PropertyInfo[] GetProperties(BindingFlags bindingAttr);
252 public virtual MemberInfo[] GetDefaultMembers() { throw NotImplemented.ByDesign; }
254 public virtual RuntimeTypeHandle TypeHandle { get { throw new NotSupportedException(); } }
255 public static RuntimeTypeHandle GetTypeHandle(object o)
258 throw new ArgumentNullException(null, SR.Arg_InvalidHandle);
259 Type type = o.GetType();
260 return type.TypeHandle;
263 public static Type[] GetTypeArray(object[] args)
266 throw new ArgumentNullException(nameof(args));
268 Type[] cls = new Type[args.Length];
269 for (int i = 0; i < cls.Length; i++)
272 throw new ArgumentNullException();
273 cls[i] = args[i].GetType();
278 public static TypeCode GetTypeCode(Type type)
281 return TypeCode.Empty;
282 return type.GetTypeCodeImpl();
284 protected virtual TypeCode GetTypeCodeImpl()
286 if (this != UnderlyingSystemType && UnderlyingSystemType != null)
287 return Type.GetTypeCode(UnderlyingSystemType);
289 return TypeCode.Object;
292 public abstract Guid GUID { get; }
294 public static Type GetTypeFromCLSID(Guid clsid) => GetTypeFromCLSID(clsid, null, throwOnError: false);
295 public static Type GetTypeFromCLSID(Guid clsid, bool throwOnError) => GetTypeFromCLSID(clsid, null, throwOnError: throwOnError);
296 public static Type GetTypeFromCLSID(Guid clsid, string server) => GetTypeFromCLSID(clsid, server, throwOnError: false);
298 public static Type GetTypeFromProgID(string progID) => GetTypeFromProgID(progID, null, throwOnError: false);
299 public static Type GetTypeFromProgID(string progID, bool throwOnError) => GetTypeFromProgID(progID, null, throwOnError: throwOnError);
300 public static Type GetTypeFromProgID(string progID, string server) => GetTypeFromProgID(progID, server, throwOnError: false);
302 public abstract Type BaseType { get; }
305 [DebuggerStepThrough]
306 public object InvokeMember(string name, BindingFlags invokeAttr, Binder binder, object target, object[] args) => InvokeMember(name, invokeAttr, binder, target, args, null, null, null);
309 [DebuggerStepThrough]
310 public object InvokeMember(string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, CultureInfo culture) => InvokeMember(name, invokeAttr, binder, target, args, null, culture, null);
311 public abstract object InvokeMember(string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, ParameterModifier[] modifiers, CultureInfo culture, string[] namedParameters);
313 public Type GetInterface(string name) => GetInterface(name, ignoreCase: false);
314 public abstract Type GetInterface(string name, bool ignoreCase);
315 public abstract Type[] GetInterfaces();
317 public virtual InterfaceMapping GetInterfaceMap(Type interfaceType) { throw new NotSupportedException(SR.NotSupported_SubclassOverride); }
319 public virtual bool IsInstanceOfType(object o) => o == null ? false : IsAssignableFrom(o.GetType());
320 public virtual bool IsEquivalentTo(Type other) => this == other;
322 public virtual Type GetEnumUnderlyingType()
325 throw new ArgumentException(SR.Arg_MustBeEnum, "enumType");
327 FieldInfo[] fields = GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
328 if (fields == null || fields.Length != 1)
329 throw new ArgumentException(SR.Argument_InvalidEnum, "enumType");
331 return fields[0].FieldType;
333 public virtual Array GetEnumValues()
336 throw new ArgumentException(SR.Arg_MustBeEnum, "enumType");
338 // We don't support GetEnumValues in the default implementation because we cannot create an array of
339 // a non-runtime type. If there is strong need we can consider returning an object or int64 array.
340 throw NotImplemented.ByDesign;
343 public virtual Type MakeArrayType() { throw new NotSupportedException(); }
344 public virtual Type MakeArrayType(int rank) { throw new NotSupportedException(); }
345 public virtual Type MakeByRefType() { throw new NotSupportedException(); }
346 public virtual Type MakeGenericType(params Type[] typeArguments) { throw new NotSupportedException(SR.NotSupported_SubclassOverride); }
347 public virtual Type MakePointerType() { throw new NotSupportedException(); }
349 public static Type MakeGenericSignatureType(Type genericTypeDefinition, params Type[] typeArguments) => new SignatureConstructedGenericType(genericTypeDefinition, typeArguments);
351 public static Type MakeGenericMethodParameter(int position)
354 throw new ArgumentException(SR.ArgumentOutOfRange_NeedNonNegNum, nameof(position));
355 return new SignatureGenericMethodParameterType(position);
358 public override string ToString() => "Type: " + Name; // Why do we add the "Type: " prefix?
360 public override bool Equals(object o) => o == null ? false : Equals(o as Type);
361 public override int GetHashCode()
363 Type systemType = UnderlyingSystemType;
364 if (!object.ReferenceEquals(systemType, this))
365 return systemType.GetHashCode();
366 return base.GetHashCode();
368 public virtual bool Equals(Type o) => o == null ? false : object.ReferenceEquals(this.UnderlyingSystemType, o.UnderlyingSystemType);
370 public static Type ReflectionOnlyGetType(string typeName, bool throwIfNotFound, bool ignoreCase) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ReflectionOnly); }
372 public static Binder DefaultBinder
376 if (s_defaultBinder == null)
378 DefaultBinder binder = new DefaultBinder();
379 Interlocked.CompareExchange<Binder>(ref s_defaultBinder, binder, null);
381 return s_defaultBinder;
385 private static volatile Binder s_defaultBinder;
387 public static readonly char Delimiter = '.';
388 public static readonly Type[] EmptyTypes = Array.Empty<Type>();
389 public static readonly object Missing = System.Reflection.Missing.Value;
391 public static readonly MemberFilter FilterAttribute = FilterAttributeImpl;
392 public static readonly MemberFilter FilterName = (m, c) => FilterNameImpl(m, c, StringComparison.Ordinal);
393 public static readonly MemberFilter FilterNameIgnoreCase = (m, c) => FilterNameImpl(m, c, StringComparison.OrdinalIgnoreCase);
395 private const BindingFlags DefaultLookup = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public;