private static TypeSignature ReadTypeSignature(
            MetadataImage image,
            IBinaryStreamReader reader,
            RecursionProtection protection)
        {
            var elementType = (ElementType)reader.ReadByte();

            switch (elementType)
            {
            case ElementType.Array:
                return(ArrayTypeSignature.FromReader(image, reader, protection));

            case ElementType.Boxed:
                return(BoxedTypeSignature.FromReader(image, reader, protection));

            case ElementType.ByRef:
                return(ByReferenceTypeSignature.FromReader(image, reader, protection));

            case ElementType.CModOpt:
                return(OptionalModifierSignature.FromReader(image, reader, protection));

            case ElementType.CModReqD:
                return(RequiredModifierSignature.FromReader(image, reader, protection));

            case ElementType.Class:
                return(TypeDefOrRefSignature.FromReader(image, reader, protection));

            case ElementType.FnPtr:
                return(FunctionPointerTypeSignature.FromReader(image, reader, protection));

            case ElementType.GenericInst:
                return(GenericInstanceTypeSignature.FromReader(image, reader, protection));

            case ElementType.MVar:
                return(GenericParameterSignature.FromReader(image, reader, GenericParameterType.Method));

            case ElementType.Pinned:
                return(PinnedTypeSignature.FromReader(image, reader, protection));

            case ElementType.Ptr:
                return(PointerTypeSignature.FromReader(image, reader, protection));

            case ElementType.Sentinel:
                return(SentinelTypeSignature.FromReader(image, reader, protection));

            case ElementType.SzArray:
                return(SzArrayTypeSignature.FromReader(image, reader, protection));

            case ElementType.ValueType:
                var type = TypeDefOrRefSignature.FromReader(image, reader, protection);
                type.IsValueType = true;
                return(type);

            case ElementType.Var:
                return(GenericParameterSignature.FromReader(image, reader, GenericParameterType.Type));

            default:
                return(MsCorLibTypeSignature.FromElementType(image, elementType));
            }
        }
        public static TypeSignature FromReader(MetadataHeader header, IBinaryStreamReader reader)
        {
            var elementType = (ElementType)reader.ReadByte();

            switch (elementType)
            {
            case ElementType.Array:
                return(ArrayTypeSignature.FromReader(header, reader));

            case ElementType.Boxed:
                return(BoxedTypeSignature.FromReader(header, reader));

            case ElementType.ByRef:
                return(ByReferenceTypeSignature.FromReader(header, reader));

            case ElementType.CModOpt:
                return(OptionalModifierSignature.FromReader(header, reader));

            case ElementType.CModReqD:
                return(RequiredModifierSignature.FromReader(header, reader));

            case ElementType.Class:
                return(TypeDefOrRefSignature.FromReader(header, reader));

            case ElementType.FnPtr:
                return(FunctionPointerTypeSignature.FromReader(header, reader));

            case ElementType.GenericInst:
                return(GenericInstanceTypeSignature.FromReader(header, reader));

            case ElementType.MVar:
                return(GenericParameterSignature.FromReader(header, reader, GenericParameterType.Method));

            case ElementType.Pinned:
                return(PinnedTypeSignature.FromReader(header, reader));

            case ElementType.Ptr:
                return(PointerTypeSignature.FromReader(header, reader));

            case ElementType.Sentinel:
                return(SentinelTypeSignature.FromReader(header, reader));

            case ElementType.SzArray:
                return(SzArrayTypeSignature.FromReader(header, reader));

            case ElementType.ValueType:
                var type = TypeDefOrRefSignature.FromReader(header, reader);
                type.IsValueType = true;
                return(type);

            case ElementType.Var:
                return(GenericParameterSignature.FromReader(header, reader, GenericParameterType.Type));

            default:
                return(MsCorLibTypeSignature.FromElementType(header, elementType));
            }
            throw new NotSupportedException();
        }
        /// <summary>
        /// Determines whether two types are considered equal according to their signature.
        /// </summary>
        /// <param name="signature1">The first type to compare.</param>
        /// <param name="signature2">The second type to compare.</param>
        /// <returns><c>True</c> if the types are considered equal, <c>False</c> otherwise.</returns>
        public bool MatchTypes(GenericParameterSignature signature1, GenericParameterSignature signature2)
        {
            if (signature1 == null && signature2 == null)
                return true;
            if (signature1 == null || signature2 == null)
                return false;

            return signature1.Index == signature2.Index
                && signature1.ElementType == signature2.ElementType;
        }