如何确定一个类型是否是运行时类型?

5

如何确定一个类型是否是RunTimeType类型?我有一个能够工作但有些笨拙的方法:

    private bool IsTypeOfType(Type type)
    {
        return type.FullName ==  "System.RuntimeType";
    }

2
你为什么需要知道那个? - svick
没有特别尝试过这个。不会用 wouldn't type == typeof(RuntimeType) 吗? - That Chuck Guy
1
@ThatChuckGuy,那行不通,因为RuntimeTypeinternal - svick
@svick 哦,好的。这说明我从来没有必须使用过一个,是吗? - That Chuck Guy
我正在使用这个工具:http://comparenetobjects.codeplex.com/ - Greg Finzer
3个回答

8
我猜您实际上想知道一个Type对象是否描述了Type类,但是Type对象是typeof(RuntimeType)而不是typeof(Type),因此将其与typeof(Type)进行比较会失败。

您可以检查由Type对象描述的类型的实例是否可以分配给Type类型的变量。这样可以得到所需的结果,因为RuntimeType派生自Type
private bool IsTypeOfType(Type type)
{
    return typeof(Type).IsAssignableFrom(type);
}

如果你真的需要知道描述Type类的Type对象,你可以使用GetType方法:
private bool IsRuntimeType(Type type)
{
    return type == typeof(Type).GetType();
}

然而,由于 typeof(Type) != typeof(Type).GetType(),因此您应该避免这样做。


示例:

IsTypeOfType(typeof(Type))                          // true
IsTypeOfType(typeof(Type).GetType())                // true
IsTypeOfType(typeof(string))                        // false
IsTypeOfType(typeof(int))                           // false

IsRuntimeType(typeof(Type))                         // false
IsRuntimeType(typeof(Type).GetType())               // true
IsRuntimeType(typeof(string))                       // false
IsRuntimeType(typeof(int))                          // false

我不明白,你的 IsTypeOfType() 不会总是返回 true 吗? - svick
@svick:我已经添加了一些示例。 - dtb
1
这里的例子不是很相关。那么像这样获取运行时类型new {}.GetType()呢?我已经尝试过了,结果是false(而应该是true),这意味着它是错误的。在.NET 4.5中,我们有TypeInfo,看起来检查type is TypeInfo似乎可以用来检查t的运行时类型是否正确。 - Hopeless
@Hopeless 我实际上点赞了你的评论,认为你是对的 - 但是后来我进行了一项测试(请参见下面的答案),发现相反的结果。我真的很想知道我是否正确。 - alelom

0

实际上,唯一的麻烦是 System.RuntimeTypeinternal 的,所以做一些简单的事情,比如:

   if (obj is System.RuntimeType)

无法编译:

CS0122 'RuntimeType' 由于其保护级别而无法访问。

因此,@dtb 上面的解决方案是正确的。在他们的答案基础上进行扩展:

void Main()
{
    object obj = "";
    // obj = new {}; // also works

    // This works
    IsRuntimeType(obj.GetType()); // Rightly prints "it's a System.Type"
    IsRuntimeType(obj.GetType().GetType()); // Rightly prints "it's a System.RuntimeType"

    // This proves that @Hopeless' comment to the accepted answer from @dtb does not work
    IsWhatSystemType(obj.GetType()); // Should return "is a Type", but doesn't
    IsWhatSystemType(obj.GetType().GetType());
}

// This works
void IsRuntimeType(object obj)
{
    if (obj == typeof(Type).GetType())
        // Can't do `obj is System.RuntimeType` -- inaccessible due to its protection level
        Console.WriteLine("object is a System.RuntimeType");
    else if (obj is Type)
        Console.WriteLine("object is a System.Type");
}

// This proves that @Hopeless' comment to the accepted answer from @dtb does not work
void IsWhatSystemType(object obj)
{
    if (obj is TypeInfo)
        Console.WriteLine("object is a System.RuntimeType");
    else
        Console.WriteLine("object is a Type");
}

在这里可以找到一个.NET Fiddle 链接


在它打印的第一行中,你可以看到它是错误的,它会打印出object is a System.Type,如果你传入new {}.GetType(),那么new {}应该是一个运行时类型,所以为了使用IsRuntimeType方法(由dtb提供),我们需要通过使用GetType(或任何其他可能的方式?)来获取它的Type,然后再检查new {}是否是运行时类型。为什么要在IsRuntimeType中传递new {}.GetType().GetType()?那会检查Type本身(即Type的类型),而不是对象类型(即new {}的类型)。 - Hopeless
谢谢您的回复。但是,我不确定我是否理解了。如果我们执行 new { }.GetType().ToString(),我们会得到 <>f__AnonymousType0。为什么您说 new {} 应该是运行时类型?我认为这不是这种情况——它不是匿名类型吗?因此有了这段代码。 - alelom
IsRuntimeType() 中,如果你传入 new {}.GetType(),它会打印 object is a System.Type(这是一个匿名类型);如果你传入 new {}.GetType().GetType(),它会打印 object is a System.RuntimeType - alelom
也许我对System.RuntimeType存在误解,它实际上只是从Type派生的类型,用于表示类型的类型(我不确定System.RuntimeType的实例是如何创建的,但也许一种方式是在Type上调用GetType())。我认为它是关于所有动态创建的类型的通用术语(这再次让我与匿名类型混淆,尽管匿名类型仍然是编译时创建的类型-它们只是被隐藏并由编译器自动生成)。因此,要测试IsRuntimeType,我们需要在运行时创建一些类型(也许使用反射发射)。 - Hopeless
我承认“匿名类型”不是一个我们可以用来测试方法“IsRuntimeType”的运行时类型。我们需要一个真实的“System.RuntimeType”实例,使用emit reflection在运行时创建一个类型并不容易,因此我不打算现在制作演示程序来进行这个检查。我也不确定那种动态创建的类型是否可以调用GetType返回System.RuntimeType - Hopeless

-1
return type == typeof(MyObjectType) || isoftype(type.BaseType) ;

1
没有解释的代码并不是很有用,尤其是如果您使用了您不解释的方法。 - svick

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