检查类型是否为TypeBuilder。

3

如何检查一个类型对象是否为TypeBuilderInstantiation

基本上,我需要使用Type的一个方法。

如果它是TypeBuilderInstantiation,我需要调用TypeBuilder.GetMethod(...)而不仅仅是theType.GetMethod(...)(因为它会抛出一个不支持的异常)。

我不能简单地检查theType是否为TypeBuilder,因为TypeBuilderInstantiation直接从Type继承(而不是TypeBuilder)。我也不能直接检查TypeBuilderInstantiation,因为它是内部类。


你如何获取那个实例?同时,如果未创建,TypeBuilder.GetMethods也会抛出异常。你想做什么? - leppie
2个回答

2

为什么不将Type.Fullname与您期望的TypeBuilderInstantiation进行比较呢?

这听起来很糟糕。您能否详细说明您正在处理内部类的内容?


我认为在调用CreateType之前,将类型参数应用于TypeBuilder时会返回TypeBuilderInstantiation的实例,但这只是猜测。 - leppie
没错,leppie。我不会乱搞任何东西。我只是生成两种不同的类型,并且需要其中一种调用另一种的方法...但是我在运行时不知道另一种是否已经被创建了。 - Jeff
我也完全不得不这样做,我只是查找StartsWith("TypeBuilder"),因为我会接受任何能减少脆弱性的方法,但是是啊,微软用一个内部类型在运行时看起来像Type,但像TypeBuilder一样运作,这真是一团糟。 - jbtule
更糟糕的是,在Mono中,TypeBuilderInstantiation被称为MonoGenericClass,并且也没有继承自TypeBuilder——想象一下吧。 - jbtule

1
我知道这是一个旧问题,但我觉得批准的答案并不是很有帮助。我从来不喜欢比较框架提供的字符串的相等性,因为如果它们在某些时候发生变化,你的应用程序就会崩溃。
因此,我创建了一些更复杂的系统,在运行时构建它们自己的类型,让我在这个线程中添加我的二十分之一。
TypeBuilderInstantiation始终是泛型类型的表示形式,由至少一个TypeBuilder和其他Type(RuntimeType、TypeBuilder和/或TypeBuilderInstantiation)组成。这意味着问题类型的泛型类型定义是TypeBuilder,或者至少一个泛型参数是TypeBuilder、GenericTypeParameterBuilder或本身是TypeBuilderInstantiation。(在GenericTypeParameterBuilder的情况下,如果它是由泛型类型本身声明的,则不计算。)
以下是如何获取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

这是一个检查类型是否为 TypeBuilderInstantiation 的巧妙实现。
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;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接