检查 Type 是否为 TypeBuilder

发布于 2024-10-12 11:42:55 字数 434 浏览 1 评论 0原文

如何检查 Type 对象是否是 TypeBuilderInstantiation

基本上,我需要一种类型之外的方法。

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

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

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

Basically, I need a method off the Type.

If it's a TypeBuilderInstantiation, 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

北城孤痞 2024-10-19 11:42:55

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

这味道很难闻。您能详细说明一下您在内部课程中所做的事情吗?

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?

温柔戏命师 2024-10-19 11:42:55

我知道这是一个老问题,但我觉得批准的答案不是很有帮助。我从来不喜欢比较框架提供的字符串的相等性,因为如果它们在某个时刻发生变化,您的应用程序就会崩溃。

因此,在创建了一些在运行时构建自己的类型的更复杂的系统后,让我在这个线程中添加我的二十美分。

TypeBuilderInstantiation 始终是泛型类型的表示,它至少由一个 TypeBuilder 和其他 Type 实例组成(RuntimeTypeTypeBuilder 和/或 TypeBuilderInstantiation)。这意味着相关类型的泛型类型定义是 TypeBuilder,或者至少其中一个泛型参数是 TypeBuilderGenericTypeParameterBuilder > 或其本身是一个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;
}

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文