Representation of Types
Types are represented by various means in PostSharp. The first important distinction is the one between types and type signatures:
- Types (IType), strictly speaking, are either classes or structures. Types may have fields, methods, properties, generic parameters and so on.
-
Type signatures (ITypeSignature) are
either intrinsic types (e.g.
int32,string,object,float, ...) either type constructions (e.g. arrays, pointers, generic constructions, ...). Type signatures may not have fields or methods in themselves (however, generic type instances have all the artifact of their generic definition).
Semantics of types are derived from semantics of type signatures.
Type Signatures
Type signatures are specified by the ITypeSignature interface and have the following semantics:
- A type signature belongs to classifications, i.e. can be tested against predicates like "the type signature is a pointer", "the type signature is a reference type", ...
- A type signature may, but must not, be declared in an assembly (for instance intrinsic types are not related to any assembly).
- A type signature can be mapped to a reflection
Type. - A type signature may contain generic arguments (i.e. reference generic parameters), and these generic arguments may be mapped to other type signatures.
- A type signature can be translated to another module than the one in which they are defined.
- A type signature can be 'undressed', i.e. some of their modifiers can be removed.
- A type signature may inherit another type signature
Note that type signatures are not necessarily metadata declarations, i.e. they do not need an entry in module metadata tables.
Types
When types are defined inside the current module, they are represented by the TypeDefDeclaration class. When they are defined in an external module or an external assembly, they are represented by the TypeRefDeclaration class.
Type constructions TypeSpecDeclaration
are a very specific case. A TypeSpecDeclaration is
basically a metadata table entry to 'wrap' a type signature.
However, when the type signature is a generic instance (i.e.
generic construction), the type construction may have fields and
methods. So generic constructions behave nearly as 'normal' types,
but they have no name.
To take this specificity into account, we defined two interfaces: IType, extended by INamedType. IType interface.
Additionally from the semantics inherited from the
ITypeSignature interface, the IType
interface has the following semantics:
- Types are always metadata declarations.
- A type can have methods and fields.
- Given an
IType, the correspondingTypeDefDeclarationcan be resolved in the current domain.
The only additional semantics of INamedType over
IType is that named types have... a name.
Generic parameters
Since generic parameters are placeholders for type signatures, they have semantics of a type signature and implement the ITypeSignature interface. See Generics for more details about generic parameters.