为什么在编译时不能将值类型的GetType()替换为字符串文字?

Dan*_*ury 2 c# compiler-optimization

编辑:这个问题是基于GetType()返回一个字符串的误解.

我正在努力更好地处理C#的工作原理,所以这个问题更具理论性而非实际性.

据我了解,在值类型上调用GetType需要装箱,然后调用方法.但是由于值类型不能继承,但是类型在编译时是已知的,那么为什么编译器不能简单地用字符串文字替换对GetType()的调用?

或者这是可以完成的事情,但是认为没有必要,因为无论如何都不需要在未装箱的值类型上调用GetType?

Eri*_*ert 5

如果您没有误解GetType返回字符串,那么让我们考虑您可能会问过的问题.编译器可以编译吗?

Foo foo = whatever;
Type t = foo.GetType();
Run Code Online (Sandbox Code Playgroud)

Type t = typeof(Foo);
Run Code Online (Sandbox Code Playgroud)

是的,这将是一个合法的优化.编译器不进行这种优化,因为如果编译器团队可以进行实际上有所不同的优化,那么编译器团队就会浪费时间进行优化.让我们考虑一下拟议的优化问题.

  • new GetType方法Foo吗?如果是这样,那么它可以做任何事情.编译器团队必须检测对原始的调用GetType.然后编写测试用例,确保在这些情况下不应用优化.
  • 如果接收器有任何副作用,则不正确.在这些情况下,编译器团队必须检测副作用并抑制优化,或者以保留副作用的方式实现优化.再次编写测试用例.
  • 这些副作用包括在我们的情况下,可能空取消引用例外Foo?而不是Foo,所以你必须拥有该编译器的一个特例.
  • 那些可能是值类型的泛型上的GetType怎么样?有许多案例需要考虑,同样,这些案例会增加优化的设计,实施和测试成本.
  • 优化可以节省单个拳击惩罚.假设的代码即将进行不必要的反思.这是否会使您成为应用程序实现高性能的关键路径上的代码?不要消除拳击; 消除反射!
  • 优化首先没有人编写的代码的优化不是有用的优化.为什么要进行反射以确定您已经知道编译时类型的表达式的类型?明智的人不会首先编写此代码,因此无需对其进行优化.
  • 或者换一种方式:如果你不小心以产生拳击转换的方式编写代码,而你想要消除它,你可以这么做.当你很容易做到时,编译器不需要为你做这件事.

因此,出于所有这些原因以及更多原因,优化的成本高于其产生的效益.

有关如何评估建议的优化的更长但类似的讨论,请参阅昨天的答案:c#编译器的奇怪行为,因为缓存委托