Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#中的私有常量和私有只读变量之间有区别吗?_C#_Constants_Readonly - Fatal编程技术网

C#中的私有常量和私有只读变量之间有区别吗?

C#中的私有常量和私有只读变量之间有区别吗?,c#,constants,readonly,C#,Constants,Readonly,在C#中使用private const变量或private static readonly变量(除了必须为const指定编译时表达式之外)有什么区别吗 因为它们都是私有的,所以没有与其他图书馆的链接。那会有什么不同吗?例如,它能带来性能差异吗?内线?有什么相似的吗?在用吗?不是真的。常量在编译时计算,而只读在运行时计算。您还可以在构造函数中为只读变量指定一个值。关于常量,需要注意的是它们实际上存储在可执行文件中,因此声明大量常量将增加可执行文件的大小 通常情况下,这不是一个大问题,但我的一个朋友

在C#中使用
private const
变量或
private static readonly
变量(除了必须为
const
指定编译时表达式之外)有什么区别吗


因为它们都是私有的,所以没有与其他图书馆的链接。那会有什么不同吗?例如,它能带来性能差异吗?内线?有什么相似的吗?

在用吗?不是真的。常量在编译时计算,而只读在运行时计算。您还可以在构造函数中为只读变量指定一个值。

关于常量,需要注意的是它们实际上存储在可执行文件中,因此声明大量常量将增加可执行文件的大小


通常情况下,这不是一个大问题,但我的一个朋友在一家公司工作,该公司实施了“一切都必须是常量”规则,并设法显著增加了编译后的可执行文件的大小。

好吧,您可以在属性中使用常量,因为它们作为编译时存在。您无法预测静态只读变量的值,因为
.cctor
可以通过配置等对其进行初始化

就用法而言,常量被烧制到调用代码中。这意味着,如果重新编译库dll以更改public常量,但不更改使用者,则使用者仍将使用原始值。如果使用只读变量,则不会发生这种情况。另一方面,常量的速度(非常非常轻微)更快,因为它只加载值(而不必取消引用)

再实习;尽管您可以手动执行此操作,但这通常是文本的编译器/运行时特性;如果通过文字初始化只读字段:

someField = "abc";

然后将实习
“abc”
。如果您从配置中读取它,它将不会被删除。因为常量字符串必须是文本,所以它也将被插入,但访问方式不同:再次强调,从字段读取是一种取消引用,而不是一种取消引用。

事实上,这两种类型在初始化后无法更改,但它们之间存在一些差异:

  • “const”必须在声明的位置初始化(在编译时),而“readonly”可以在声明的位置或构造函数内部初始化(ar运行时)
例如,在这种情况下可以使用const:

public class MathValues
{
  public const double PI = 3.14159;
}
对于这种情况,readonly会更好:

public class Person
{
    public readonly DateTime birthDate;

    public Person(DateTime birthDate)
    {
        this.birthDate = birthDate;
    }
}

  • “const”是静态的,因此它在该类的所有实例之间共享,并且可以直接访问(如MathValues.PI),而“readonly”不是静态的。因此,像“static const”这样的声明是非法的,因为const是静态的,而“static readonly”是合法的

  • “const”只能保存整型(sbyte、byte、short、ushort、int、uint、long、ulong、char、float、double、decimal、bool或string)、枚举或对null的引用(不是类或结构,因为它们是在运行时用“new”关键字初始化的),而“readonly”可以保存复杂的类型、结构或类(通过在初始化时使用new关键字)但不能保存枚举


只读字段可以在声明时初始化,也可以在类的构造函数中初始化。因此,根据使用的构造函数,只读字段可以具有不同的值

只读成员也可以用于运行时常量,如下例所示:

public static readonly uint currentTicks = (uint)DateTime.Now.Ticks;
只读字段不是隐式静态的,因此,如果需要,static关键字可以(必须)显式应用于只读字段。对于隐式静态的常量字段,这是不允许的


只读成员可以通过在初始化时使用new关键字来保存复杂对象。

以下是C#.NET常量、只读字段和静态只读字段(从)之间的区别

常数

  • 默认情况下是静态的
  • 必须有编译时间值(即:可以有“A”+“B”,但不能有方法调用)
  • 可以在属性中使用
  • 被复制到使用它们的每个程序集中(每个程序集都获得值的本地副本)
  • 可以在函数中声明
只读实例字段

  • 在创建实例时计算
  • 在构造函数退出时必须具有设置值
静态只读字段

  • 当代码执行命中类引用时(即:创建新实例或执行静态方法)计算
  • 必须在静态构造函数完成时计算值
  • 您确实不想将ThreadStaticAttribute放在这些线程上(因为静态构造函数将仅在一个线程中执行,并且它将为其线程设置值;所有其他线程都将未初始化该值)

不同之处在于,静态只读字段的值在运行时设置,因此可以由包含类修改,而常量字段的值设置为编译时常量

在静态只读情况下,只允许包含类修改它

在变量声明中(通过变量初始值设定项) 在静态构造函数中(实例构造函数,如果不是静态的) 如果const声明中不允许字段类型,或者编译时不知道该值,则通常使用静态只读

还允许使用实例只读字段

请记住,对于引用类型,在这两种情况下(静态和实例),readonly修饰符只会阻止您将新引用指定给字段。它特别不会使引用指向的对象不可变

class Program

{

  public static readonly Test test = new Test();

  static void Main(string[] args)

  {

     test.Name = "Program";

     test = new Test(); // Error: A static readonly field cannot be assigned to (except in a static constructor or a variable initializer)

  }

}

class Test

{

   public string Name;

}

不同之处在于,静态只读可以由包含类修改,但const永远不能修改,并且必须为b
class Program

{

  public static readonly Test test = new Test();

  static void Main(string[] args)

  {

     test.Name = "Program";

     test = new Test(); // Error: A static readonly field cannot be assigned to (except in a static constructor or a variable initializer)

  }

}

class Test

{

   public string Name;

}
private const int[] values = new int[] { 1, 2, 3 };
private static readonly int[] values = new int[] { 1, 2, 3 };
private static readonly int?[] values = new int?[] { null, 1, 2, 3 };
public const DateTime dt = DateTime.Today;  //throws compilation error
public const string Name = string.Empty;    //throws compilation error
public readonly string Name = string.Empty; //No error, legal
class A
{
    public readonly int Id;

    public A(int i)
    {
        Id = i;
    }
}
A objOne = new A(5);
A objTwo = new A(10);