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

标签 c# compiler-optimization

编辑:这个问题是基于对 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/

相关文章:

vb.net - 是否总是分配函数的默认返回变量?

c# - 使用存储库模式实现依赖注入(inject)的困惑 - c# EF Core

lisp - "How to apply Red to compile-time optimization of this Lisp code?"

c - 英特尔 icc : how to dump optimized code as C file

c# - 如何检查本地 OneDrive 文件夹是否同步?

C# 编译器优化循环?

c++ - 要测试代码更改的结果,我是否总是需要重新构建整个东西?

c# - 在 WSO2 APIM/DSS 服务中使用自定义密码加密

c# - 是什么导致我的构造函数中的 "this"指针为空?

c# - TransformPoint() 方法附加到哪个对象的变换重要吗?