开发者

Check if Type is a TypeBuilder

How can I check if a Type object is a TypeBuilderInstantiation?

Basically, I need a method off the Type.

If it's a TypeBu开发者_运维技巧ilderInstantiation, I need to call TypeBuilder.GetMethod(...), not just theType.GetMethod(...) (because it throws a not supported exception).

I can't simply check if theType is TypeBuilder because TypeBuilderInstantiation inherits directly from Type (not TypeBuilder). I can't check directly against TypeBuilderInstantiation, because it's internal.


Why not compare Type.Fullname to what you're expecting for TypeBuilderInstantiation?

This smells bad. Can you elaborate on what you're doing that you're mucking around with an internal class?


I know this is an old question, but I feel the approved answer is not very helpful. I've never liked having to compare equality of strings that are provided by the framework, because if they change at some point your application breaks down.

Therefore, having created some more complex systems that build their own types in runtime, let me add my twenty cents in this thread.

A TypeBuilderInstantiation is ALWAYS a representation of a generic type, that consists of at least one TypeBuilder and then other instances of Type (RuntimeType, TypeBuilder and/or TypeBuilderInstantiation). This means that either the generic type definition of the type in question is a TypeBuilder or at least one of the generic arguments is a TypeBuilder, a GenericTypeParameterBuilder or itself a TypeBuilderInstantiation. (In case of GenericTypeParameterBuilder if it is declared by the generic type itself, it does not count.)

Here's an example how to get instances of TypeBuilderInstantiation:

AssemblyName myAssemblyName = new AssemblyName("MyAssembly");
AssemblyBuilder myAssembly = AppDomain.CurrentDomain.DefineDynamicAssembly(myAssemblyName, AssemblyBuilderAccess.Run);
ModuleBuilder myModule = myAssembly.DefineDynamicModule("MyModule");
TypeBuilder myType = myModule.DefineType("MyType");
//myType (MyType) is TypeBuilder
Type collectionType = typeof(Collection<>).MakeGenericType(myType);
//collectionType (Collection<MyType>) is TypeBuilderInstantiation

TypeBuilder myGenericType = myModule.DefineType("MyGenericType");
GenericTypeParameterBuilder myGenericParam = myGenericType.DefineGenericParameters("T")[0];
//myGenericType (MyGenericType<T>) is TypeBuilder
Type genericType = myType.MakeGenericType(typeof(string));
//genericType (MyGenericType<string>) is TypeBuilderInstantiation

TypeBuilder myOtherGenericType = myModule.DefineType("MyOtherGenericType");
GenericTypeParameterBuilder myOtherGenericParam = myOtherGenericType.DefineGenericParameters("S")[0];
Type otherGenericType = myType.MakeGenericType(myOtherGenericParam);
//otherGenericType (MyGenericType<S>) is TypeBuilderInstantiation

Here's a nifty little implementation to check whether a type is a TypeBuilderInstantiation or not.

public static bool IsTypeBuilderInstantiation(Type type)
{
    bool isTypeBuilderInstantiation = false;
    if (type.IsGenericType && !(type is TypeBuilder))
    {
        foreach (var genericTypeArg in type.GetGenericArguments())
        {
            if (isTypeBuilderInstantiation = (
                genericTypeArg is TypeBuilder ||
                genericTypeArg is GenericTypeParameterBuilder ||
                IsTypeBuilderInstantiation(genericTypeArg)))
                break;
        }
        isTypeBuilderInstantiation |= type.GetGenericTypeDefinition() is TypeBuilder;
    }
    return isTypeBuilderInstantiation;
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜