简体   繁体   English

在.NET中,为什么在编译时而不是JIT时评估常量?

[英]In .NET, why are constants evaluated at compile time rather than at JIT time?

I got a bit of a surprise today when I changed the value of a publicly-visible constant in a static class and then replaced an old copy of the assembly with the newly-compiled version. 今天,当我在静态类中更改了公共可见常量的值,然后用新编译的版本替换了程序集的旧副本时,我感到有些惊讶。 The surprise was that the existing program that referenced the assembly didn't pick up the new value of the constant. 令人惊讶的是,引用该程序集的现有程序未使用该常数的新值。 That is, I didn't re-compile the executable but rather just replaced that one assembly. 也就是说,我没有重新编译可执行文件,而是替换了那个程序集。

A full description of my experiment is at How constant is a constant? 我的实验的完整描述在常数是多少?

I'll admit to being very surprised by this behavior. 我承认对此行为感到非常惊讶。 I understand what's going on, but I don't understand why . 我了解发生了什么,但我不明白为什么 Is there a particular technical reason why constants couldn't be picked up at JIT time rather than compile time? 是否有特定的技术原因导致无法在JIT时间而不是编译时间获取常量? Are there cases where doing that would break things? 在某些情况下这样做会破坏事情吗?

Constants are supposed to be constant . 常量应该是常量 For all time . 一直以来 Constants are things like the value of pi, or the number of protons in a lead atom. 常数是诸如pi的值或铅原子中质子数之类的东西。

If your constant changes, it wasn't really a constant ; 如果您的常数不断变化, 那实际上不是常数 use a readonly field instead. 请改用只读字段。

Also see the Framework Design Guidelines, which state: 另请参阅框架设计指南,其中指出:

Use constant fields for constants that will never change. 将常量字段用于永远不变的常量。 The compiler burns the values of const fields directly into calling code. 编译器将const字段的值直接刻录到调用代码中。 Therefore const values can never be changed without the risk of breaking compatibility. 因此,如果没有破坏兼容性的风险,则永远不能更改const值。

Essentially, changing a constant without recompiling everything that depends on it is every bit as broken as changing the signature of a method without recompiling everything that depends on it. 从本质上讲,在不重新编译依赖于常量的所有内容的情况下更改常量就象在不重新编译依赖于该常量的所有方法的情况下更改方法的签名一样。 The compiler "bakes in" all kinds of assumptions about information about metadata from referenced assemblies when it compiles a dependent assembly. 编译器在编译从属程序集时会“引用”关于来自引用程序集的元数据信息的各种假设。 If you make any change, you cannot expect things to simply keep on working. 如果进行任何更改,您将无法期望事情会继续正常运行。

There is also a third way to declare "constants": a public static property. 还有第三种声明“常量”的方法:公共静态属性。

public static string ConstString {get{return "First test";}}

This has the versioning semantics of a readonly field, but if the jitter inlines the getter it becomes a jit-time constant. 它具有只读字段的版本控制语义,但是如果抖动内联吸气剂,它将成为一个jit-time常量。 And unlike const it can be used on user defined types. 并且与const不同,它可以用于用户定义的类型。

I think it's a good idea to use static properties for value-types and string, but not for user defined classes, since you don't want to allocate a new instance on each property access. 我认为对值类型和字符串使用静态属性是一个好主意,但对于用户定义的类则不要使用静态属性,因为您不想在每个属性访问上分配新的实例。

I used this in my FixedPoint type like this: 我在固定点类型中使用了以下代码:

public struct FixedPoint
{
  private int raw;
  private const fracDigits=16;

  private FixedPoint(int raw)
  {
    this.raw=raw;
  }

  public static FixedPoint Zero{get{return new FixedPoint();}}
  public static FixedPoint One{get{return new FixedPoint(1<<fracDigits);}}
  public static FixedPoint MaxValue{get{return new FixedPoint(int.MaxValue);}}
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 常量和编译时评估 - 为什么要更改此行为 - Constants and compile time evaluation - Why change this behaviour nameof()是在编译时评估的吗? - Is nameof() evaluated at compile-time? 编译时间常量和引用类型 - Compile time constants and reference types Azure Functions RunOnStartUp 在配置中设置而不是在编译时? - Azure Functions RunOnStartUp set in configuration rather than at compile time? DataTestMethods 的非编译时间常量 - Non-compile time constants for DataTestMethods 使用方法在编译时创建常量 - Using methods to create constants at compile time 如何在 C# /.Net.Core 中定义基于平台(Linux vs Windows)的编译时间常数? - How to define compile time constants based on platform (Linux vs Windows) in C# / .Net.Core? 为什么C#4.0中的可选参数需要编译时常量? - Why do optional parameters in C# 4.0 require compile-time constants? C# - 为什么DateTime.MinValue和MaxValue不是编译时常量? - C# - Why are DateTime.MinValue and MaxValue not compile-time constants? 什么时候x:静态类型转换器评估:运行时或编译时? - When are x:Static type converters evaluated: runtime or compile time?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM