如何阻止C#用它们的值replaceconstvariables?

我们有一个编译成名为consts.dll的DLL的项目,其中包含如下内容:

public static class Consts { public const string a = "a"; public const string b = "b"; public const string c = "c"; } 

我们有这种types的多个项目,每个编译成一个同名(consts.dll)的DLL,我们根据需要replace它们。 我们有另一个类使用这些常量:

 public class ConstsUser { string f() { return Consts.a; } } 

不幸的是, Consts.a被优化为“a”,所以即使我们replaceConsts.dll实现,我们仍然得到“a”而不是正确的值,我们需要重新编译ConstsUser 。 有没有办法阻止优化器用它们的值replaceconstvariables?

我认为使用static readonly修改符合您的需求:

 public static class Consts { public static readonly string a = "a"; public static readonly string b = "b"; public static readonly string c = "c"; } 

常量是硬编码的电话网站,所以这是你的问题。 静态只读variables只能在Consts类的variables声明或静态构造函数中Consts ,并且不会在呼叫站点内联。

从书CLR通过c#

当代码引用一个常量符号时,编译器在定义该常量的程序集的元数据中查找符号,提取该常量的值,并将该值embedded发出的中间语言(IL)代码中 。 因为常量的值直接embedded代码中,所以常量在运行时不需要为它们分配任何内存 。 另外,你不能得到一个常量的地址,你不能通过引用传递一个常量。 这些约束也意味着常量没有一个好的交叉汇编版本控制的故事,所以只有当你知道符号的值永远不会改变的时候才应该使用它们

正如我们所看到的,当我们知道一个符号的值永远不会改变时,使用const会有好处。 它可以执行得更快,因为CLR不需要parsing值。

实际上,在构build应用程序程序集之后,DLL程序集甚至不会在运行时加载,并且可以从磁盘中删除,因为编译器甚至不会在应用程序的元数据中添加对DLL程序集的引用。

正如@Sergey Berezovskiy所build议的那样,如果您需要CLR 在运行时dynamicparsing该值,则可以使用static readonly 。 性能受此解决scheme的影响,但也有另一个好处。

另外,一个字段可以是任何数据types ,所以你不必限制自己的编译器内置的原始types(就像你对常量做的那样)。