常量和字段

作者:追风剑情 发布于:2021-5-7 9:26 分类:C#

常量

常量是值从不变化的符号。定义常量符号时,它的值必须能在编译时确定。确定后,编译器将常量值保存到程序集元数据中。这意味着只能定义编译器识别的基元类型的常量。在C#中,以下类型是基元类型,可用于定义常量 :BooleanCharByteSByteInt16UInt16Int32UInt32Int64UInt64SingleDoubleDecimalString。然而,C#也允许定义非基元类型的常量变量(constant variable),前提是把值设为null

示例——非基元类型常量的值必须为null
public sealed class SomeType
{
    //SomeType不是基元类型,但C#允许
    //值为null的这种类型的常量变量
    public const SomeType Empty = null;
}

编译器会将常量值嵌入引用它的位置。所以如果引用的是DLL中的常量,当这个DLL中的常量值变化时,应用程序要想获取到新值也得重新编译。如果希望在运行时从一个程序集中提取另一个程序集中的值,那么不应该使用常量,而应该使用 readonly 字段。

示例——获取csc.exe所在路径
//转载 https://www.cnblogs.com/talentzemin/p/10944493.html
var frameworkPath = RuntimeEnvironment.GetRuntimeDirectory();
var cscPath = Path.Combine(frameworkPath, "csc.exe");

// C:\Windows\Microsoft.NET\Framework\v4.0.30319
Console.WriteLine(frameworkPath);
// C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe
Console.WriteLine(cscPath);

在CMD中输入: csc /target:library /out:Test.dll SomeType.cs 编译成DLL

字段

字段是一种数据成员,其中容纳了一个值类型的实例或者对一个引用类型的引用。

CLR 支持类型(静态)字段和实例(非静态)字段。如果是类型字段,容纳字段数据所需的动态内存是在类型对象中分配的,而类型对象是在类型加载到一个AppDomain时创建的。那么,什么时候类型加载到一个AppDomain中呢?这通常是在引用了该类型的任何方法首次进行JIT编译的时候。如果是实例字段,容纳字段数据所需的动态内存是在构造类型的实例时分配的。

字段修饰符
CLR术语 C#术语 说明
Static static 这种字段是类型状态的一部分,而不是对象状态的一部分
Instance (默认) 这种字段与类型的一个实例关联,而不是与类型本身关联
InitOnly readonly 这种字段只能由一个构造器方法中的代码写入
Volatile volatile 编译器、CLR 和硬件不会对访问这种字段的代码执行 “线程不安全” 的优化措施。只有以下类型才能标记为 volatile: 所有引用类型,Single,Boolean,Byte,SByte,Int16,UInt16,Int32,UInt32,Char,以及基础类型为 Byte,SByte,Int16,UInt16,Int32或UInt32的所有枚举类型。volatile字段将在 “基元线程同步构造” 讨论。

由于字段存储在动态内存中,所以它们的值在运行时才能获取。字段还解决了常量存在的版本控制问题。此外,字段可以是任何数据类型,不像常量那样仅仅局限于编译器内置的基元类型。

CLR 支持 readonly 字段和 read/write 字段。大多数字段都是 read/write 字段,意味着在代码执行过程中,字段值可多次改变。但 readonly 字段只能在构造器方法中写入。(构造器方法只能调用一次,即对象首次创建时)编译器和验证机制确保 readonly 字段不会被构造器以外的任何方法写入。注意,可利用反射来修改 readonly 字段

示例——readonly
//其他代码可以修改chars数组元素,但不能修改它的引用
public static readonly Char[] chars = new Char[] {'A', 'B', 'C'};

标签: C#

Powered by emlog  蜀ICP备18021003号-1   sitemap

川公网安备 51019002001593号