Is there a difference between private const and private readonly variables in C#?
在C中有一个
因为它们都是私有的,所以没有与其他图书馆的链接。那会有什么不同吗?例如,它能改变性能吗?实习弦?有类似的吗?
好吧,您可以在属性中使用const,因为它们作为编译时存在。您不能预测静态只读变量的值,因为
在用法上,常量被烧掉到调用代码中。这意味着,如果重新编译库dll以更改公共常量,但不更改使用者,则使用者仍将使用原始值。如果使用只读变量,则不会发生这种情况。反过来,常数(非常,非常轻微)更快,因为它只加载值(而不必取消引用)。
重新实习;尽管您可以手动执行此操作,但这通常是文本的编译器/运行时功能;如果您通过文本初始化只读字段:
1 | someField ="abc"; |
然后,
实际上,这两种类型在初始化后无法更改,但它们之间存在一些差异:
- "const"必须在声明的位置初始化(在编译时),而"readonly"可以在声明的位置或在构造函数(ar运行时)内初始化。
例如,在这种情况下可以使用const:
1 2 3 4 | public class MathValues { public const double PI = 3.14159; } |
对于这种情况,只读更好:
1 2 3 4 5 6 7 8 9 | public class Person { public readonly DateTime birthDate; public Person(DateTime birthDate) { this.birthDate = birthDate; } } |
或
1 2 3 4 |
"const"是静态的,因此它在该类的所有实例之间共享,可以直接访问(如mathvalues.pi),而"readonly"不是静态的。因此,像"static const"这样的声明是非法的,因为const是静态的,但"static readonly"是合法的
"const"只能保存整型(sbyte、byte、short、ushort、int、uint、long、ulong、char、float、double、decimal、bool或string)、枚举或对空值的引用(不是类或结构,因为它们是在运行时用"new"关键字初始化的),而"readonly"可以保存复杂类型、结构或类(通过使用n初始化时的ew关键字),但不能保存枚举
关于常量,需要注意的是它们实际上存储在可执行文件中,因此声明大量常量会增加可执行文件的大小。
通常,这不是一个大问题,但我的一个朋友在一家公司工作,该公司强制执行"一切都必须是常量"规则,并设法显著增加其编译的可执行文件的大小。
这里是C.NET常量、只读字段和静态只读字段之间的区别(来自本文)。
常数:
- 默认为静态
- 必须有编译时间值(即:可以有"a"+"b",但不能有方法调用)
- 可用于属性
- 复制到使用它们的每个程序集中(每个程序集都获取值的本地副本)
- 无法在函数中声明
只读实例字段:
- 在创建实例时计算
- 必须在构造函数退出时设置值
静态只读字段:
- 当代码执行命中类引用(即创建新实例或执行静态方法)时进行评估。
- 静态构造函数完成时必须已计算出值
- 您确实不想将threadstaticattribute放在这些线程上(因为静态构造函数只在一个线程中执行,它将为其线程设置值;所有其他线程都将具有未初始化的该值)
在C.NET中,const和readonly字段之间存在显著差异。
常量在默认情况下是静态的,需要用常量值初始化,以后不能修改。构造函数中也不允许更改值。它不能与所有数据类型一起使用。对于ex-datetime。它不能与datetime数据类型一起使用。
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 |
只读可以声明为静态,但不是必需的。声明时不需要初始化。它的值可以使用构造函数进行分配或更改。因此,它在用作实例类成员时具有优势。两个不同的实例化可能具有不同的只读字段值。对于前
1 2 3 4 5 6 7 8 9 | class A { public readonly int Id; public A(int i) { Id = i; } } |
然后,只读字段可以用即时特定的值初始化,如下所示:
这里,实例objone的readonly字段值为5,objtwo的readonly字段值为10。使用const是不可能的。
还有一件事。我在上面的评论中没有看到这一点,尽管我可能已经错过了。不能创建常量数组。
1 |
但您可以使用静态只读字段来创建它。
1 |
因此,如果需要数组常量(例如允许值的列表),并且枚举不合适,那么静态只读是唯一的方法。例如,如果数组是可以为空的整数,如下所示:
1 |
不能用常数来做吗?
在使用中?不是真的。常量在编译时计算,而只读则在运行时计算。也可以在构造函数中为只读变量赋值。
区别在于静态只读字段的值在运行时设置,因此可以由包含类修改,而常量字段的值设置为编译时常量。
在静态只读情况下,只允许包含类修改它
在变量声明中(通过变量初始值设定项)在静态构造函数中(实例构造函数,如果不是静态的话)如果常量声明中不允许字段类型,或者编译时不知道该值,则通常使用静态只读。
也允许使用实例只读字段。
请记住,对于引用类型,在这两种情况下(静态和实例),只读修饰符只会阻止您为字段分配新的引用。它不会使引用指向的对象不可变。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
区别在于静态只读可以由包含类修改,但const不能修改,必须初始化为编译时常量。要稍微扩展静态只读情况,包含类只能修改它:
--在变量声明中(通过变量初始值设定项)。
--在静态构造函数中(如果不是静态的,则为实例构造函数)。
c.net中的const关键字
示例:
示例:
只读字段可以在声明处或类的构造函数中初始化。因此,根据所使用的构造函数,只读字段可以具有不同的值。
只读成员也可用于运行时常量,如下例所示:
1 | public static readonly uint currentTicks = (uint)DateTime.Now.Ticks; |
只读字段不是隐式静态的,因此如果需要,静态关键字可以(必须)显式应用于只读字段。这对于隐式静态的常量字段是不允许的。
只读成员可以在初始化时使用new关键字来保存复杂对象。