先放上两段代码。
代码1:
using System;
public class MyClass
{
public static void Main(){
Console.WriteLine(Test.STR_1);
Console.WriteLine(Test.STR_2);
Console.ReadLine();
}
public class Test
{
public const string STR_1 = "Str1";
public static readonly string STR_2;
static Test()
{
STR_2 = "Str2";
}
}
}
代码2:
using System;
namespace
{
public class MyClass
{
// Constructors
public MyClass (){ }
// Methods
public static void Main (){
Console.WriteLine("Str1");
Console।WriteLine(MyClass.Test.STR_2);
Console.ReadLine();
}
// Nested Types
public class Test
{
// Constructors
static Test ()
{
MyClass.Test.STR_2 = "Str2";
}
public Test () { }
// Constants
public const string STR_1 = "Str1";
// Statics
public static readonly string STR_2;
}
}
}
代码1和代码2最大的区别在于:代码2是使用反射技术从代码1编译生成的可执行文件"反编译"出来的。
贴这两段代码的目的就是为了说明一下static readonly 和const的区别。从代码2中可以看到,代码1里面的所有使用常量Test.STR_1的地方(只有一处,用红色标识),都被直接替换成了常量Test.STR_1所代表的字符串。而使用静态只读变量Test.STR_2的地方,代码1和代码2没有任何区别。
为什么会有这种情况?
因为常量在编译的时候值就已经被确定了,为了提高效率,编译器直接把程序中使用到的常量都替换为常量所代表的值了。
为什么我会想起来写这个?
因为我习惯把所用到的字符串和其他一些共用的值都表示为常量,放在一个独立的类库里,以便使用,结果,今天这个"以便"变成了不便。我修改了这个独立类库里面的某些字符串的值,编译类库之后,替换了服务器上的版本,现在大家都知道后果是什么了。由于服务器上引用这个类库的地方都是之前编译过的,唯独这个类库是新的,一个崭新的常量类库,可惜程序不会使用这些崭新的值,大家老老实实继续使用编译器提供的之前的常量代表的值。
为这事儿折腾了快两个小时,终于,想起了某个时候听说的关于常量的不方便之处,所以就出来提醒大家,以后尽量使用static readonly吧,更何况readonly还可以在构造函数中被赋值,呵呵。
没有评论:
发表评论