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;
}
精彩评论