final class · System

Type

public final class Type

A type at run time: typeof(T) and x.GetType() give the same object for the same type (compare with ==).

Tipo
final class
Espacio de nombres
System
Ensamblado
System.Core
Acceso
public, final
Archivo fuente
Reflection.ant

Herencia

Clases base
Any Type

Propiedades

str Name { get; }
#

read-only

The type's name (without its namespace or type arguments): List, Int32, Int32[].

str Namespace { get; }
#

read-only

str FullName { get; }
#

read-only

The namespace, the name and the type arguments: System.Collections.Generic.List<System.Int32>.

Type? BaseType { get; }
#

read-only

The base class (null for any, interfaces, values and the types made from others).

bool IsClass { get; }
#

read-only

bool IsValueType { get; }
#

read-only

bool IsInterface { get; }
#

read-only

bool IsEnum { get; }
#

read-only

bool IsPrimitive { get; }
#

read-only

bool IsArray { get; }
#

read-only

bool IsPointer { get; }
#

read-only

bool IsGenericType { get; }
#

read-only

bool IsAbstract { get; }
#

read-only

bool IsSealed { get; }
#

read-only

bool IsPublic { get; }
#

read-only

bool IsFunction { get; }
#

read-only

A function type (func<…> : R or func*<…> : R).

bool IsNullable { get; }
#

read-only

A nullable value type (T? of a value type).

Type[] GenericTypeArguments { get; }
#

read-only

Métodos

override ToString() : str
#

override

GetGenericArguments() : Type[]
#

The type arguments (of a generic type, a nullable, a function type).

GetElementType() : Type?
#

What an array or a pointer holds (null otherwise).

GetArrayRank() : i32
#

An array's dimensions.

GetInterfaces() : Type[]
#

The interfaces the type implements (its own and its base classes').

IsFriendOf(Type other) : bool
#

Whether this type derives from other (a class below it, not the class itself). Whether [FriendOf] on this type names other, or the other way round: each sees the other's friendly members.

static Names(Type on, Type friend) : bool
#

static

IsSubclassOf(Type other) : bool
#
IsAssignableFrom(Type? other) : bool
#

Whether a value of other can be a value of this type: the same type, a class below it, a type that implements it (this an interface), anything for any.

IsInstanceOfType(any? value) : bool
#

Whether value is one of this type.

GetFields() : FieldInfo[]
#

The public fields (instance and static, inherited ones too).

GetFields(BindingFlags wanted) : FieldInfo[]
#
GetField(str name) : FieldInfo?
#

The public field named name (null: none).

GetField(str name, BindingFlags wanted) : FieldInfo?
#
GetProperties() : PropertyInfo[]
#
GetProperties(BindingFlags wanted) : PropertyInfo[]
#
GetProperty(str name) : PropertyInfo?
#
GetProperty(str name, BindingFlags wanted) : PropertyInfo?
#
GetMethods() : MethodInfo[]
#

The public methods (instance and static, inherited ones too; overridden ones once).

GetMethods(BindingFlags wanted) : MethodInfo[]
#
GetMethod(str name) : MethodInfo?
#

The public method named name (the first, when it has overloads; null: none).

GetMethod(str name, BindingFlags wanted) : MethodInfo?
#
GetMethod(str name, Type[] types) : MethodInfo?
#

The public method named name that takes types.

GetConstructors() : ConstructorInfo[]
#
GetConstructors(BindingFlags wanted) : ConstructorInfo[]
#
GetConstructor(Type[] types) : ConstructorInfo?
#

The public constructor that takes types (null: none).

GetEnumNames() : str[]
#

An enum's member names, in declaration order.

GetEnumValues() : i64[]
#

An enum's member values (as numbers), in declaration order.

GetCustomAttributes() : any[]
#

The custom attributes written on the type.

GetCustomAttributes(Type attributeType) : any[]
#

Those of the attribute class attributeType (or a class below it).

IsDefined(Type attributeType) : bool
#

Whether an attribute of attributeType is written on the type.

MakeArrayType() : Type
#

T[].

MakeArrayType(i32 rank) : Type
#

T[,]… (rank dimensions).

MakePointerType() : Type
#

T*.

Miembros privados e internos (60)

readonly str name
#

private

readonly str space
#

private

readonly i32 flags
#

private

readonly TypeDescriber describer
#

private

bool described
#

private

Base, arguments, interfaces and element: from the describer, once.

Type? baseType
#

private

Type[] arguments
#

private

Type[] interfaces
#

private

Type? element
#

private

i32 rank
#

private

FieldInfo[]? fields
#

private

PropertyInfo[]? properties
#

private

MethodInfo[]? methods
#

private

ConstructorInfo[]? constructors
#

private

private

The public constructor without parameters (Activator), once found.

bool plainLooked
#

private

Type? arrayType
#

private

Types made from this one (T[], T*, T?), once each.

Type? pointerType
#

private

Type? nullableType
#

private

List<Type>? grids
#

private

static Reentrant sync
#

private static

What makes each type's Type once, even with threads (the slow path of typeof only).

static Dictionary<str, Type>? made
#

private static

Types that are not one of the program's (functions, the unknown): by full name.

static ClassFlag() : i32
#

private static

What flags says.

static ValueFlag() : i32
#

private static

static InterfaceFlag() : i32
#

private static

static EnumFlag() : i32
#

private static

static PrimitiveFlag() : i32
#

private static

static ArrayFlag() : i32
#

private static

static GenericFlag() : i32
#

private static

static AbstractFlag() : i32
#

private static

static FinalFlag() : i32
#

private static

static PointerFlag() : i32
#

private static

static NullableFlag() : i32
#

private static

static FunctionFlag() : i32
#

private static

static StaticFlag() : i32
#

private static

static PublicFlag() : i32
#

private static

static BitflagsFlag() : i32
#

private static

Has(i32 flag) : bool
#

private

Describe()
#

private

static Made(str key, str name, str space, i32 flags, TypeDescriber describer) : Type
#

private static

static Join(Type[] parts) : str
#

private static

static Holds(List<Type> types, Type type) : bool
#

private static

static Shadowed(List<PropertyInfo> found, str name) : bool
#

private static

A property of a class below with the same name was found first.

static Overridden(List<MethodInfo> found, MethodInfo method) : bool
#

private static

The same method of a class below (its override) was found first.

Matches(BindingFlags wanted, bool isPublic, bool isStatic) : bool
#

private

OwnFields() : FieldInfo[]
#

internal

OwnProperties() : PropertyInfo[]
#

internal

OwnMethods() : MethodInfo[]
#

internal

OwnConstructors() : ConstructorInfo[]
#

internal

PlainConstructor() : ConstructorInfo?
#

internal

What Activator.CreateInstance(type) uses: the public constructor without parameters (null: none).

ZeroValue() : any
#

internal

A new value of a value type with no constructor: its zero value.

new(str name, str space, i32 flags, TypeDescriber describer)
#

internal

Called by the compiler's code: a type it describes.

static Enter()
#

internal static

The reflection lock (taken while a type's Type is made).

static Exit()
#

internal static

static ArrayOf(Type element, i32 rank) : Type
#

internal static

T[] (rank 1) or T[,]…

static PointerOf(Type target) : Type
#

internal static

static NullableOf(Type inner) : Type
#

internal static

A nullable value type T?.

static FuncOf(Type[] parameters, Type result, bool native) : Type
#

internal static

A function type: func<…> : R (or func*<…> : R when native).

static VoidType() : Type
#

internal static

void (the result of a function that gives nothing).

static Unknown() : Type
#

internal static

A type the program does not describe.

Miembros heredados (4)

Código fuente

Type en Antril, descompilado a partir de su Larva HIR.

System.Type.ant
// System.Type — System.Core (decompiled from Larva HIR)

import System.Reflection;

into namespace System
{
	/// A type at run time: `typeof(T)` and `x.GetType()` give the same object for the same type (compare with `==`).
	public final class Type
	{
		readonly str name;
		readonly str space;
		readonly i32 flags;
		readonly TypeDescriber describer;

		/// Base, arguments, interfaces and element: from the describer, once.
		bool described;
		Type? baseType;
		Type[] arguments;
		Type[] interfaces;
		Type? element;
		i32 rank;
		FieldInfo[]? fields;
		PropertyInfo[]? properties;
		MethodInfo[]? methods;
		ConstructorInfo[]? constructors;

		/// The public constructor without parameters (Activator), once found.
		ConstructorInfo? plain;
		bool plainLooked;

		/// Types made from this one (T[], T*, T?), once each.
		Type? arrayType;
		Type? pointerType;
		Type? nullableType;
		List<Type>? grids;

		/// What makes each type's Type once, even with threads (the slow path of typeof only).
		static Reentrant sync;

		/// Types that are not one of the program's (functions, the unknown): by full name.
		static Dictionary<str, Type>? made;

		/// What `flags` says.
		static ClassFlag() : i32 => 1;

		static ValueFlag() : i32 => 2;

		static InterfaceFlag() : i32 => 4;

		static EnumFlag() : i32 => 8;

		static PrimitiveFlag() : i32 => 16;

		static ArrayFlag() : i32 => 32;

		static GenericFlag() : i32 => 64;

		static AbstractFlag() : i32 => 128;

		static FinalFlag() : i32 => 256;

		static PointerFlag() : i32 => 512;

		static NullableFlag() : i32 => 1024;

		static FunctionFlag() : i32 => 2048;

		static StaticFlag() : i32 => 4096;

		static PublicFlag() : i32 => 8192;

		static BitflagsFlag() : i32 => 16384;

		Has(i32 flag) : bool => (flags & flag) != 0;

		Describe()
		{
			if (described)
				return;
			sync.Enter();
			if (!described)
			{
				baseType = describer.Base();
				arguments = describer.Arguments();
				interfaces = describer.Interfaces();
				element = describer.Element();
				rank = describer.Rank();
				described = true;
			}
			sync.Exit();
		}

		static Made(str key, str name, str space, i32 flags, TypeDescriber describer) : Type
		{
			sync.Enter();
			if (made == null)
				made = new Dictionary<str, Type>();
			Dictionary<str, Type> all = made ?? new Dictionary<str, Type>();
			Type result = all.ContainsKey(key) ? all.Get(key) : new Type(name, space, flags, describer);
			all.Set(key, result);
			sync.Exit();
			return result;
		}

		static Join(Type[] parts) : str
		{
			str text = "";
			loop (i32 i = 0..parts.Length)
				text = i == 0 ? parts[i].FullName : text + ", " + parts[i].FullName;
			return text;
		}

		static Holds(List<Type> types, Type type) : bool
		{
			{
				ListIterator<Type> _iterator0 = types.Iterator();
				loop (_iterator0.Next())
				{
					Type t = _iterator0.Current;
					{
						if (t == type)
							return true;
					}
				}
			}
			return false;
		}

		/// A property of a class below with the same name was found first.
		static Shadowed(List<PropertyInfo> found, str name) : bool
		{
			{
				ListIterator<PropertyInfo> _iterator0 = found.Iterator();
				loop (_iterator0.Next())
				{
					PropertyInfo p = _iterator0.Current;
					{
						if (p.Name == name)
							return true;
					}
				}
			}
			return false;
		}

		/// The same method of a class below (its override) was found first.
		static Overridden(List<MethodInfo> found, MethodInfo method) : bool
		{
			{
				ListIterator<MethodInfo> _iterator0 = found.Iterator();
				loop (_iterator0.Next())
				{
					MethodInfo m = _iterator0.Current;
					{
						if (m.SameAs(method))
							return true;
					}
				}
			}
			return false;
		}

		Matches(BindingFlags wanted, bool isPublic, bool isStatic) : bool
		{
			if (wanted == BindingFlags.Default)
				wanted = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public;
			bool access = isPublic ? (wanted & BindingFlags.Public) != BindingFlags.Default : (wanted & BindingFlags.NonPublic) != BindingFlags.Default;
			bool where = isStatic ? (wanted & BindingFlags.Static) != BindingFlags.Default : (wanted & BindingFlags.Instance) != BindingFlags.Default;
			return access && where;
		}

		internal:
			OwnFields() : FieldInfo[]
			{
				if (fields is FieldInfo[] known)
					return known;
				FieldInfo[] list = describer.Fields(this);
				fields = list;
				return list;
			}

			OwnProperties() : PropertyInfo[]
			{
				if (properties is PropertyInfo[] known)
					return known;
				PropertyInfo[] list = describer.Properties(this);
				properties = list;
				return list;
			}

			OwnMethods() : MethodInfo[]
			{
				if (methods is MethodInfo[] known)
					return known;
				MethodInfo[] list = describer.Methods(this);
				methods = list;
				return list;
			}

			OwnConstructors() : ConstructorInfo[]
			{
				if (constructors is ConstructorInfo[] known)
					return known;
				ConstructorInfo[] list = describer.Constructors(this);
				constructors = list;
				return list;
			}

			/// What Activator.CreateInstance(type) uses: the public constructor without parameters (null: none).
			PlainConstructor() : ConstructorInfo?
			{
				if (plainLooked)
					return plain;
				{
					ConstructorInfo[] _items0 = OwnConstructors();
					i32 _index1 = 0;
					loop (_index1 < _items0.Length)
					{
						ConstructorInfo c = _items0[_index1];
						{
							if (c.IsPublic && c.GetParameters().Length == 0)
								plain = c;
						}
						_index1++;
					}
				}
				plainLooked = true;
				return plain;
			}

			/// A new value of a value type with no constructor: its zero value.
			ZeroValue() : any => describer.Construct(-1, Activator.None);

			/// Called by the compiler's code: a type it describes.
			new(str name, str space, i32 flags, TypeDescriber describer)
			{
				this.name = name;
				this.space = space;
				this.flags = flags;
				this.describer = describer;
				arguments = [];
				interfaces = [];
			}

			/// The reflection lock (taken while a type's Type is made).
			static Enter()
			{
				sync.Enter();
			}

			static Exit()
			{
				sync.Exit();
			}

			/// `T[]` (`rank` 1) or `T[,]`…
			static ArrayOf(Type element, i32 rank) : Type => rank == 1 ? element.MakeArrayType() : element.MakeArrayType(rank);

			static PointerOf(Type target) : Type => target.MakePointerType();

			/// A nullable value type `T?`.
			static NullableOf(Type inner) : Type
			{
				if (inner.nullableType is Type known)
					return known;
				sync.Enter();
				Type result = inner.nullableType ?? new Type(inner.name + "?", inner.space, ValueFlag() | NullableFlag() | GenericFlag() | PublicFlag(), new PartsDescriber(null, [inner], 0, null));
				inner.nullableType = result;
				sync.Exit();
				return result;
			}

			/// A function type: `func<…> : R` (or `func*<…> : R` when `native`).
			static FuncOf(Type[] parameters, Type result, bool native) : Type
			{
				str key = (native ? "func*<" : "func<") + Join(parameters) + "> : " + result.FullName;
				List<Type> all = new List<Type>();
				{
					Type[] _items2 = parameters;
					i32 _index3 = 0;
					loop (_index3 < _items2.Length)
					{
						Type p = _items2[_index3];
						all.Add(p);
						_index3++;
					}
				}
				all.Add(result);
				Type[] parts = all.ToArray();
				i32 kind = native ? PointerFlag() | FunctionFlag() | PublicFlag() : ClassFlag() | FunctionFlag() | GenericFlag() | PublicFlag() | FinalFlag();
				return Made(key, native ? "func*" : "func", "", kind, new PartsDescriber(null, parts, 0, null));
			}

			/// `void` (the result of a function that gives nothing).
			static VoidType() : Type
			{
				return Made("void", "Void", "System", ValueFlag() | PublicFlag(), new PartsDescriber(null, [], 0, null));
			}

			/// A type the program does not describe.
			static Unknown() : Type => Made("?", "?", "", 0, new PartsDescriber(null, [], 0, null));

		public:
			override ToString() : str => FullName;

			/// The type arguments (of a generic type, a nullable, a function type).
			GetGenericArguments() : Type[]
			{
				Describe();
				return arguments;
			}

			/// What an array or a pointer holds (null otherwise).
			GetElementType() : Type?
			{
				Describe();
				return element;
			}

			/// An array's dimensions.
			GetArrayRank() : i32
			{
				Describe();
				return rank;
			}

			/// The interfaces the type implements (its own and its base classes').
			GetInterfaces() : Type[]
			{
				Describe();
				List<Type> all = new List<Type>();
				Type? at = this;
				loop (at is Type current)
				{
					current.Describe();
					{
						Type[] _items3 = current.interfaces;
						i32 _index4 = 0;
						loop (_index4 < _items3.Length)
						{
							Type i = _items3[_index4];
							{
								if (!Holds(all, i))
									all.Add(i);
							}
							_index4++;
						}
					}
					at = current.baseType;
				}
				return all.ToArray();
			}

			/// Whether this type derives from `other` (a class below it, not the class itself).
			/// Whether `[FriendOf]` on this type names `other`, or the other way round: each sees the other's `friendly` members.
			IsFriendOf(Type other) : bool => Names(this, other) || Names(other, this);

			static Names(Type on, Type friend) : bool
			{
				{
					any[] _items0 = on.GetCustomAttributes();
					i32 _index1 = 0;
					loop (_index1 < _items0.Length)
					{
						any a = _items0[_index1];
						{
							if (a is FriendOfAttribute f && f.Friend == friend)
								return true;
						}
						_index1++;
					}
				}
				return false;
			}

			IsSubclassOf(Type other) : bool
			{
				Type? at = BaseType;
				loop (at is Type current)
				{
					if (current == other)
						return true;
					at = current.BaseType;
				}
				return false;
			}

			/// Whether a value of `other` can be a value of this type: the same type, a class below it, a type that
			/// implements it (this an interface), anything for `any`.
			IsAssignableFrom(Type? other) : bool
			{
				if (other == null)
					return false;
				Type from = other ?? this;
				if (from == this)
					return true;
				if (Has(ClassFlag()) && name == "Any" && space == "System")
					return true;
				if (from.IsSubclassOf(this))
					return true;
				if (Has(InterfaceFlag()))
				{
					{
						Type[] _items1 = from.GetInterfaces();
						i32 _index2 = 0;
						loop (_index2 < _items1.Length)
						{
							Type i = _items1[_index2];
							{
								if (i == this || i != from && IsAssignableFrom(i))
									return true;
							}
							_index2++;
						}
					}
				}
				return false;
			}

			/// Whether `value` is one of this type.
			IsInstanceOfType(any? value) : bool => value is any some && IsAssignableFrom(some.GetType());

			/// The public fields (instance and static, inherited ones too).
			GetFields() : FieldInfo[] => GetFields(BindingFlags.Default);

			GetFields(BindingFlags wanted) : FieldInfo[]
			{
				List<FieldInfo> found = new List<FieldInfo>();
				Type? at = this;
				loop (at is Type current)
				{
					{
						FieldInfo[] _items3 = current.OwnFields();
						i32 _index4 = 0;
						loop (_index4 < _items3.Length)
						{
							FieldInfo f = _items3[_index4];
							{
								if (Matches(wanted, f.IsPublic, f.IsStatic) && (current == this || !f.IsStatic && f.IsPublic))
									found.Add(f);
							}
							_index4++;
						}
					}
					at = (wanted & BindingFlags.DeclaredOnly) != BindingFlags.Default ? null : current.BaseType;
				}
				return found.ToArray();
			}

			/// The public field named `name` (null: none).
			GetField(str name) : FieldInfo? => GetField(name, BindingFlags.Default);

			GetField(str name, BindingFlags wanted) : FieldInfo?
			{
				{
					FieldInfo[] _items0 = GetFields(wanted);
					i32 _index1 = 0;
					loop (_index1 < _items0.Length)
					{
						FieldInfo f = _items0[_index1];
						{
							if (f.Name == name)
								return f;
						}
						_index1++;
					}
				}
				return null;
			}

			GetProperties() : PropertyInfo[] => GetProperties(BindingFlags.Default);

			GetProperties(BindingFlags wanted) : PropertyInfo[]
			{
				List<PropertyInfo> found = new List<PropertyInfo>();
				Type? at = this;
				loop (at is Type current)
				{
					{
						PropertyInfo[] _items3 = current.OwnProperties();
						i32 _index4 = 0;
						loop (_index4 < _items3.Length)
						{
							PropertyInfo p = _items3[_index4];
							{
								if (Matches(wanted, p.IsPublic, p.IsStatic) && (current == this || !p.IsStatic) && !Shadowed(found, p.Name))
									found.Add(p);
							}
							_index4++;
						}
					}
					at = (wanted & BindingFlags.DeclaredOnly) != BindingFlags.Default ? null : current.BaseType;
				}
				return found.ToArray();
			}

			GetProperty(str name) : PropertyInfo? => GetProperty(name, BindingFlags.Default);

			GetProperty(str name, BindingFlags wanted) : PropertyInfo?
			{
				{
					PropertyInfo[] _items0 = GetProperties(wanted);
					i32 _index1 = 0;
					loop (_index1 < _items0.Length)
					{
						PropertyInfo p = _items0[_index1];
						{
							if (p.Name == name)
								return p;
						}
						_index1++;
					}
				}
				return null;
			}

			/// The public methods (instance and static, inherited ones too; overridden ones once).
			GetMethods() : MethodInfo[] => GetMethods(BindingFlags.Default);

			GetMethods(BindingFlags wanted) : MethodInfo[]
			{
				List<MethodInfo> found = new List<MethodInfo>();
				Type? at = this;
				loop (at is Type current)
				{
					{
						MethodInfo[] _items3 = current.OwnMethods();
						i32 _index4 = 0;
						loop (_index4 < _items3.Length)
						{
							MethodInfo m = _items3[_index4];
							{
								if (Matches(wanted, m.IsPublic, m.IsStatic) && (current == this || !m.IsStatic) && !Overridden(found, m))
									found.Add(m);
							}
							_index4++;
						}
					}
					at = (wanted & BindingFlags.DeclaredOnly) != BindingFlags.Default ? null : current.BaseType;
				}
				return found.ToArray();
			}

			/// The public method named `name` (the first, when it has overloads; null: none).
			GetMethod(str name) : MethodInfo? => GetMethod(name, BindingFlags.Default);

			GetMethod(str name, BindingFlags wanted) : MethodInfo?
			{
				{
					MethodInfo[] _items0 = GetMethods(wanted);
					i32 _index1 = 0;
					loop (_index1 < _items0.Length)
					{
						MethodInfo m = _items0[_index1];
						{
							if (m.Name == name)
								return m;
						}
						_index1++;
					}
				}
				return null;
			}

			/// The public method named `name` that takes `types`.
			GetMethod(str name, Type[] types) : MethodInfo?
			{
				{
					MethodInfo[] _items0 = GetMethods();
					i32 _index1 = 0;
					loop (_index1 < _items0.Length)
					{
						MethodInfo m = _items0[_index1];
						{
							if (m.Name == name && m.Takes(types))
								return m;
						}
						_index1++;
					}
				}
				return null;
			}

			GetConstructors() : ConstructorInfo[] => GetConstructors(BindingFlags.Instance | BindingFlags.Public);

			GetConstructors(BindingFlags wanted) : ConstructorInfo[]
			{
				List<ConstructorInfo> found = new List<ConstructorInfo>();
				{
					ConstructorInfo[] _items1 = OwnConstructors();
					i32 _index2 = 0;
					loop (_index2 < _items1.Length)
					{
						ConstructorInfo c = _items1[_index2];
						{
							if (Matches(wanted, c.IsPublic, false))
								found.Add(c);
						}
						_index2++;
					}
				}
				return found.ToArray();
			}

			/// The public constructor that takes `types` (null: none).
			GetConstructor(Type[] types) : ConstructorInfo?
			{
				{
					ConstructorInfo[] _items0 = GetConstructors();
					i32 _index1 = 0;
					loop (_index1 < _items0.Length)
					{
						ConstructorInfo c = _items0[_index1];
						{
							if (c.Takes(types))
								return c;
						}
						_index1++;
					}
				}
				return null;
			}

			/// An enum's member names, in declaration order.
			GetEnumNames() : str[] => describer.EnumNames();

			/// An enum's member values (as numbers), in declaration order.
			GetEnumValues() : i64[] => describer.EnumValues();

			/// The custom attributes written on the type.
			GetCustomAttributes() : any[] => describer.Attributes(-1);

			/// Those of the attribute class `attributeType` (or a class below it).
			GetCustomAttributes(Type attributeType) : any[] => Attributes.Of(GetCustomAttributes(), attributeType);

			/// Whether an attribute of `attributeType` is written on the type.
			IsDefined(Type attributeType) : bool => GetCustomAttributes(attributeType).Length > 0;

			/// `T[]`.
			MakeArrayType() : Type
			{
				if (arrayType is Type known)
					return known;
				sync.Enter();
				Type result = arrayType ?? new Type(name + "[]", space, ClassFlag() | ArrayFlag() | FinalFlag() | PublicFlag(), new PartsDescriber(this, [], 1, null));
				arrayType = result;
				sync.Exit();
				return result;
			}

			/// `T[,]`… (`rank` dimensions).
			MakeArrayType(i32 rank) : Type
			{
				if (rank == 1)
					return MakeArrayType();
				sync.Enter();
				if (grids == null)
					grids = new List<Type>();
				List<Type> all = grids ?? new List<Type>();
				Type? found = null;
				{
					ListIterator<Type> _iterator2 = all.Iterator();
					loop (_iterator2.Next())
					{
						Type g = _iterator2.Current;
						{
							if (g.GetArrayRank() == rank)
								found = g;
						}
					}
				}
				Type result = found ?? new Type(name + "[" + ",".Repeat(rank - 1) + "]", space, ClassFlag() | ArrayFlag() | FinalFlag() | PublicFlag(), new PartsDescriber(this, [], rank, null));
				if (found == null)
					all.Add(result);
				sync.Exit();
				return result;
			}

			/// `T*`.
			MakePointerType() : Type
			{
				if (pointerType is Type known)
					return known;
				sync.Enter();
				Type result = pointerType ?? new Type(name + "*", space, PointerFlag() | ValueFlag() | PublicFlag(), new PartsDescriber(this, [], 0, null));
				pointerType = result;
				sync.Exit();
				return result;
			}

			/// The type's name (without its namespace or type arguments): `List`, `Int32`, `Int32[]`.
			str Name
			{
				get => name;
			}

			str Namespace
			{
				get => space;
			}

			/// The namespace, the name and the type arguments: `System.Collections.Generic.List<System.Int32>`.
			str FullName
			{
				get
				{
					if (Has(ArrayFlag()) || Has(PointerFlag()) && !Has(FunctionFlag()))
					{
						Describe();
						if (element is Type of)
							return of.FullName + name.Substring(of.name.Length);
					}
					if (Has(NullableFlag()))
					{
						Describe();
						return arguments[0].FullName + "?";
					}
					str text = space.Length > 0 ? space + "." + name : name;
					if (Has(GenericFlag()))
					{
						Describe();
						if (Has(FunctionFlag()))
						{
							List<Type> parameters = new List<Type>();
							loop (i32 i = 0..arguments.Length - 1)
								parameters.Add(arguments[i]);
							return text + "<" + Join(parameters.ToArray()) + "> : " + arguments[arguments.Length - 1].FullName;
						}
						if (space == "System" && name == "String" && arguments.Length == 1 && arguments[0].name == "UInt8")
							return text;
						return text + "<" + Join(arguments) + ">";
					}
					return text;
				}
			}

			/// The base class (null for `any`, interfaces, values and the types made from others).
			Type? BaseType
			{
				get
				{
					Describe();
					return baseType;
				}
			}

			bool IsClass
			{
				get => Has(ClassFlag());
			}

			bool IsValueType
			{
				get => Has(ValueFlag());
			}

			bool IsInterface
			{
				get => Has(InterfaceFlag());
			}

			bool IsEnum
			{
				get => Has(EnumFlag());
			}

			bool IsPrimitive
			{
				get => Has(PrimitiveFlag());
			}

			bool IsArray
			{
				get => Has(ArrayFlag());
			}

			bool IsPointer
			{
				get => Has(PointerFlag()) && !Has(FunctionFlag());
			}

			bool IsGenericType
			{
				get => Has(GenericFlag());
			}

			bool IsAbstract
			{
				get => Has(AbstractFlag());
			}

			bool IsSealed
			{
				get => Has(FinalFlag());
			}

			bool IsPublic
			{
				get => Has(PublicFlag());
			}

			/// A function type (`func<…> : R` or `func*<…> : R`).
			bool IsFunction
			{
				get => Has(FunctionFlag());
			}

			/// A nullable value type (`T?` of a value type).
			bool IsNullable
			{
				get => Has(NullableFlag());
			}

			Type[] GenericTypeArguments
			{
				get
				{
					Describe();
					return arguments;
				}
			}
	}
}
Esc