Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 哪个更有效:myType.GetType()还是typeof(myType)?_C#_.net_Runtime Type - Fatal编程技术网

C# 哪个更有效:myType.GetType()还是typeof(myType)?

C# 哪个更有效:myType.GetType()还是typeof(myType)?,c#,.net,runtime-type,C#,.net,Runtime Type,假设我有一个类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()或typeo

假设我有一个类
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()的性能是否足以使在静态字段中保存类型变得有益?

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

typeof(SomeType)
是一个简单的元数据标记查找

GetType()
是一个虚拟调用;如果派生类型是子类,那么在正的一面可以得到派生类型;如果派生类型是子类,那么在负的一面可以得到派生类。如果你明白我的意思。此外,
GetType()
需要对结构进行装箱,对于可为空的结构不起作用


如果您在编译时知道类型,请使用基本相同的
typeof()。虽然typeof可以用于非实例类,如

typeof(MyClass);
但是

甚至不会生成,因为您需要该类的实例


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

唯一的方法是测量

“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);
var sw=System.Diagnostics.Stopwatch.StartNew();
对于(int i=0;i<10000000;i++)
{
var y=typeof(Program).ToString();
}
sw.Stop();
控制台写入线(软件延迟毫秒);
sw.Restart();
对于(int i=0;i<10000000;i++)
{
var y=typeReference.ToString();
}
sw.Stop();
控制台写入线(软件延迟毫秒);
也就是说,这个问题没有明确的要求,这有点令人担忧。如果您注意到性能问题,您可能已经对其进行了分析,并知道哪个选项更好。这告诉我,这很可能是过早的优化——你知道有句谚语,“过早的优化是万恶之源”

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


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

它们完全不同

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

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

两者都适用于不同的场景

您不能使用
typeof(MyType)
,除非您在编译时知道类型并有权访问它

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


typeof(MyType)
总是更有效,但是如果在编译时看不到类型,就不能使用。您不能使用
typeof(MyType)
来了解某个变量的实际运行时类型,因为您不知道该类型。

您是在运行时获取实例(动态、泛型?)还是在compiletime指定的?@newStackExchangeInstance我只是在我提供的确切代码的上下文中提问。这些都是好的观点,但我更关心的是效率,而不是可读性。
GetType
如何要求对结构进行装箱?@Dan,因为它是一个无法重写的虚拟调用。所有其他结构方法(Equals、ToString、GetHashCode等)都可以重写,这允许通过调用或约束调用调用它们,而无需装箱。但是在结构上调用非重写方法需要装箱,然后在对象上调用虚拟方法。明白了。我从来没想过。谢谢@但有一个有趣的观察结果是,在所有涉及结构的非泛型情况下,编译器实际上可以(但不会)将GetType()替换为typeof。虽然nullable-T的“正确”行为值得怀疑。我知道我提供的所有3个变量赋值在功能上是等效的,但我想知道哪一个更有效。从技术上讲typeof会更快。我只会从技术上讲。我不知道怎么才能不。你凭什么说它更有效率?我已经修改了我的职位。由于typeof(Class)返回System.Type对象,两种语法形式将使用相同的机制。如前所述,唯一的区别是typeof只能用于非实例类和对象。GetType()要求对象是实例化的。“非实例类”到底是什么意思?如果回答有点说教,我道歉,我只是想象谷歌拿起这个,成千上万的初学者突然扔掉了typeof()操作符!我明白
        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);