internal ProjectionCollectionType(TypeKind kind, Type type, ProjectionFactory factory)
            : base(type, kind, factory)
        {
            // Must register before getting key/item types, due to possible cycles
            // Example: A -> IList<B> -> B -> IList<B>
            factory.RegisterProjectionType(this);

            Type keyType, itemType;
            GetSubtypes(out keyType, out itemType);

            this.keyType  = factory.GetProjectionTypeUnsafe(keyType );
            this.itemType = factory.GetProjectionTypeUnsafe(itemType);
        }
        internal ProjectionStructureType(Type type, ProjectionFactory factory)
            : base(type, TypeKind.Structure, factory)
        {
            // Ensure base types exist before self
            //   - Safe because no type can have itself as a base (i.e. no cycles)
            //   - Causes inits to be called in order from more-base to more-derived
            int basePropertyCount;
            baseTypes = CollectBaseTypes(type, out basePropertyCount);

            // Register self
            //   - Required before creating metaobjects that can refer back to this type
            factory.RegisterProjectionType(this);

            // Create members after registration
            //   - Members can be of any type and thus can form cycles
            properties = CollectProperties(type, basePropertyCount);
        }
 internal ProjectionOpaqueType(Type type, ProjectionFactory factory)
     : base(type, TypeKind.Opaque, factory)
 {
     factory.RegisterProjectionType(this);
 }