编辑:这个问题是基于对 GetType() 返回字符串的误解。
我正试图更好地了解 C# 的工作原理,因此这个问题的理论性大于实际性。
据我了解,在值类型上调用 GetType 需要装箱,然后调用该方法。但是,由于无法继承值类型,因此类型在编译时是已知的,那么为什么编译器不能简单地将对 GetType() 的调用替换为字符串文字?
或者这是可以完成的事情,但认为没有必要,因为无论如何都不需要对未装箱的值类型调用 GetType?
最佳答案
如果您没有错误地认为 GetType 返回一个字符串,让我们考虑一下您可能会问的问题。编译器能否编译
Foo foo = whatever;
Type t = foo.GetType();
作为
Type t = typeof(Foo);
是的,这将是一个合法的优化。编译器不会进行该优化,因为编译器团队进行该优化会浪费时间,而他们本可以进行实际产生影响的优化。让我们考虑一下建议的优化。
Foo
上有新的 GetType
方法吗?如果是这样,那么它可以做任何事情。编译器团队必须检测对原始GetType
的调用。然后编写测试用例,确保在这些情况下不应用优化。- 如果接受者有任何副作用,这是不正确的。编译器团队必须检测副作用并在这些情况下抑制优化,或者以保留副作用的方式实现优化。并再次编写测试用例。
- 这些副作用包括在我们使用
Foo?
而不是Foo
的情况下可能出现的空取消引用异常,因此您必须有一个特殊情况在编译器中。 - 在可能是值类型的泛型上使用 GetType 怎么样?那里有很多情况需要考虑,同样,这些会增加优化的设计、实现和测试成本。
- 优化节省了一次拳击惩罚。假设代码即将进行不必要的反射。您认为这是否是应用程序实现高性能的关键路径上的代码?不要消除拳击;消除反射!
- 优化一开始就没有人编写的代码的优化不是有用的优化。为什么要进行反射来确定您在编译时已经知道类型的表达式的类型?懂事的人一开始不会写这段代码,所以没必要优化。
- 或者换句话说:如果您不小心按照产生装箱转换的方式编写了代码,并且您想要消除它,您可以轻松地做到这一点。当您自己很容易做的时候,编译器就不需要为您做。
因此,由于所有这些以及更多原因,优化的成本高于其产生的 yield 。
有关如何评估提议的优化的更长时间但类似的讨论,请参阅昨天的回答:Weird behaviour of c# compiler due caching delegate
关于c# - 为什么不能在编译时将值类型上的 GetType() 替换为字符串文字?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41940463/