13

假设我有一堂课MyType

sealed class MyType
{
    static Type typeReference = typeof(MyType);
    //...
}

给定以下代码:

var instance = new MyType();
var type1 = instance.GetType();
var type2 = typeof(MyType);
var type3 = typeReference;

这些变量分配中哪一个是最有效的?

GetType() 或 typeof() 的性能是否足以使在静态字段中保存类型是有益的?

4

5 回答 5

21

typeof(SomeType)是一个简单的元数据令牌查找

GetType()是虚拟通话;从好的方面来说,如果它是子类,您将获得派生类型,但在不利方面,如果它是子类,您将获得派生类。如果你明白我的意思。此外,GetType()需要对结构进行装箱,并且不适用于可为空的结构。

如果您在编译时知道类型,请使用typeof().

于 2013-05-24T17:38:20.140 回答
5

我会选择type2。它不需要实例化实例来获取类型。它是人类可读性最强的。

于 2013-05-24T17:34:31.880 回答
4

找出答案的唯一方法是测量。

“type1”变体在任何方面都不可靠或不推荐,因为并非所有类型都可以构造。更糟糕的是,它分配了需要作为垃圾收集器的内存并调用对象构造函数。

对于剩下的两个选项,在我的机器上,“type3”在调试和发布模式下的速度大约是“type1”的两倍。请记住,这仅适用于我的测试——结果可能不适用于其他处理器类型、机器类型、编译器或 .NET 版本。

        var sw = System.Diagnostics.Stopwatch.StartNew();
        for (int i = 0; i < 10000000; i++)
        {
            var y = typeof(Program).ToString();
        }
        sw.Stop();
        Console.WriteLine(sw.ElapsedMilliseconds);

        sw.Restart();
        for (int i = 0; i < 10000000; i++)
        {
            var y = typeReference.ToString();
        }
        sw.Stop();
        Console.WriteLine(sw.ElapsedMilliseconds);

也就是说,在没有明确要求的情况下提出这个问题有点令人担忧。如果您注意到性能问题,您可能已经对其进行了分析并知道哪个选项更好。这告诉我这很可能是过早的优化——你知道这句话,“过早的优化是万恶之源”。

编程代码不仅仅通过性能来衡量。它还通过正确性、开发人员生产力和可维护性来衡量。没有充分理由增加代码的复杂性只是将成本转移到其他地方。对于现在和未来的应用程序维护者来说,本来可能不是问题的事情现在变成了生产力的严重损失。

我的建议是始终使用“type1”变体。我列出的测量代码不是真实世界的场景。将 typeof 缓存到引用变量可能会产生很多副作用,尤其是在 .NET 加载程序集的方式方面。与其只在需要时加载它们,不如在每次使用应用程序时最终都加载它们——将理论性能优化变成一个非常实际的性能问题。

于 2013-05-27T21:25:41.287 回答
3

他们比较不同。

typeof(MyType)获取一个Type对象,该对象描述使用该指令MyType在 compile-type 中解析的类型。ldtoken

myInstance.GetType()获取描述变量Type运行时类型的对象。myInstance

两者都适用于不同的场景。

typeof(MyType)除非您在编译时知道类型并且可以访问它,否则您无法使用。

myInstance.GetType()除非您有该类型的实例,否则您不能使用。

typeof(MyType)总是更高效,但如果在编译时看不到类型,则无法使用。你不能typeof(MyType)用来学习某个变量的真正运行时类型,因为你不知道类型。

于 2013-05-31T00:57:00.523 回答
-1

两者基本相同。虽然 typeof 可以用于非实例类,如

typeof(MyClass);

MyClass.GetType();

甚至不会构建,因为您需要拥有该类的实例。

长话短说,他们都在不同的环境中做同样的工作。

于 2013-05-24T17:38:33.203 回答