日期:2014-05-19  浏览次数:21112 次

C# 静态类成员的问题
static   class   Defines
        {
                static   public   readonly   string[]   KeyWords;

                static   Defines()
                {
                        KeyWords   =   new   string[]   {   "end "   };
                }
        }

class   Program
        {
                static   void   Main(string[]   args)
                {
                        Console.WriteLine(Defines.KeyWords[0]);
                        Defines.KeyWords[0]   =   "10 ";
                        Console.WriteLine(Defines.KeyWords[0]);
                }
        }

这样竟然输出,
end
10
不知是我不了解内幕,还是。。。
请指教,谢谢

------解决方案--------------------

不输出
end
10,
lz想输出啥?
------解决方案--------------------
你输出的是对的!@
------解决方案--------------------
就是输出这样啊,看来lz还不了解static的意思,static只是修饰成员成类级别的,并不是不能改变啊!const就不能改变了
------解决方案--------------------
为你的常量选择readonly而不是const(译)

对于常量,C#里有两个不同的版本:运行时常量和编译时常量。
因为他们有不同的表现行为,所以当你使用不当时,将会损伤程序性能或者出现错误。
两害相权取其轻,当我们不得不选择一个的时候,我们宁可选择一个运行慢一点但正确的那一个,而不是运行快一点但有错误的那个。基于这个理由,你应该选择运行时常量而不是编译时常量(译注:这里隐藏的说明了编译时常量效率更高,但可能会有错误)。
编译时常量更快更直接,但在可维护性上远不及运行时常量。保留编译时常量是为了满足那些对性能要求克刻,且随着程序运行时间的过去,其值永远不发生改变的常量使用的(译注:这说明编译时常量是可以不被C#采用的,但考虑到性能问题,还是做了保留)。
你可以用关键字readonly来声明(declare)一个运行时常量,编译时常量是用关键字const声明的。
//Compile time constant:
public cocnst int _Millennium = 2000;
//Runtime constant:
public static readonly int _ThisYear = 2007;//(译注:原文为2004)
编译时常量与运行时常量不同之处表现在如何对他们的访问上。
一个编译时常量会被目标代码中的值直接取代。下面的代码:
if(myDateTime.Year == _Millennium)
会与下面写的代码编译成完全相同的IL代码:
if(myDateTime.Year == 2000)

运行时常量的值是在运行时确定的。当你引用一个只读常量时(read-only)IL会为你引用一个运行时常量的变量,而不是直接使用该值。
当你任意的使用其中一个常量时,这些区别就在一些限制上表现出来。编译时常量只能是基本类型(primitive types)(built-in integral and floating-poing types),枚举或者是字符串。这些就是你只能给运行时常量在初始化时赋值的类型。这些基本类就是可以被编译器在编译IL代码时直接用真实的值所取代的数据类型。下面的代码块(construct)不能通过编译。你不能用new运算符初始化一个编译时常量,即使这个数据类型是值类型。
//Does not complie, use readonly instead:
private const DateTime _classCreation = new DateTime(2000,1,1,0,0,0);
(译注:DateTime是一个值类型数据,但上面的代码因为用了new运算符,编译器无法在编译确定具体的对象应该用什么样的实际值来取代,所以无法通过编译。)

编译时常量仅限于数字和字符串。只读变量,也就是运行时常量,在构造函数(constructor)执行完成后它们是不以能被修改的。但只读变量是所有不同的,因为他们是在运行时才赋值的。当你使用运行时常量时,你有更大的可伸缩性。有一点要注意的是,运行时常量可以是任何类型的数据。而且你必须在构造函数里对他们初始化,或者你可以用任何一个初始化函数来完成。你可以添加一个DateTime结构的只读变量(--运行时常量),但你不能添加一个DateTime结构的(编译时)常量。

你可以把每一个实例(的常量)指定为只读的,从而为每一个类的实例存放不同的值。与编译时常量不同的是,它只能是静态的。
(译注:简单的讲,运行时常量可以是一个类的实例成员,也可以是一个类型的静态成员,而编译时常量只能是静态成员,因此类似:static const string m_name;的代码是不能通过编译的。)

只读数据最重要的区别是他们在运行时才确定值。当你使用只读变量 时,IL会为你产生一个对只读变量引用,而不是直接产生数值。随着时间的推移,这个区别在(系统)维护上有深远的潜在影响。
编译时常量生成的IL代码就跟直接使用数值时生成的IL是一样的,即使是在跨程序集时:一个程序集里的编译时常量在另一个程序集会保留着同样的值(译注:这里说的不是很清楚,看后面的这个例子可能会更清楚一些)。