private const
在 C# 中具有变量或变量之间是否有区别private static readonly
(除了必须分配const
编译时表达式)?
由于它们都是私有的,因此没有与其他库的链接。那么它会有什么不同吗?例如,它可以产生性能差异吗?实习字符串?有什么类似的吗?
好吧,您可以在属性中使用 const,因为它们作为编译时存在。您无法预测静态只读变量的值,因为.cctor
可以从配置等初始化它。
在使用方面,常量被烧录到调用代码中。这意味着如果您重新编译库dll 以更改公共常量,但不更改消费者,那么消费者仍将使用原始值。使用只读变量不会发生这种情况。与此相反的是,常量(非常非常轻微)更快,因为它只是加载值(而不是必须取消引用它)。
重新实习;尽管您可以手动执行此操作,但这通常是文字的编译器/运行时功能;如果您通过文字初始化只读字段:
someField = "abc";
然后"abc"
将被拘留。如果您从配置中读取它,则不会。因为常量字符串必须是文字,它也将被实习,但访问方式不同:再次,从字段中读取是取消引用,而不是ldstr
.
确实,这两种类型在初始化后就无法更改,但是它们之间还是有一些区别的:
例如 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;
}
}
或者
public class Person
{
public readonly DateTime birthDate = new DateTime(1986, 1, 24);
}
'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关键字)但不能保存枚举
关于常量需要注意的是它们实际上存储在您的可执行文件中,因此声明其中的大量常量会增加您的可执行文件大小。
通常,这不是一个大问题,但我的一个朋友在公司工作,该公司强制执行“一切都必须是 const”规则并设法显着增加其编译的可执行文件大小。
以下是 C# .NET const、readonly和static readonly字段之间的区别(来自这篇文章)。
常数:
只读实例字段:
静态只读字段:
C#.Net 中的const和readonly字段之间存在显着差异
const 默认是静态的,需要用常量值初始化,以后不能修改。构造函数中也不允许更改值。它不能用于所有数据类型。对于前日期时间。它不能与 DateTime 数据类型一起使用。
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
readonly 可以声明为静态的,但不是必需的。声明时无需初始化。可以使用构造函数分配或更改其值。因此,它在用作实例类成员时具有优势。两个不同的实例化可能具有不同的只读字段值。对于前 -
class A
{
public readonly int Id;
public A(int i)
{
Id = i;
}
}
然后可以使用即时特定值初始化只读字段,如下所示:
A objOne = new A(5);
A objTwo = new A(10);
在这里,实例 objOne 的只读字段值为 5,而 objTwo 的值为 10。使用 const 是不可能的。
正在使用?并不真地。Consts 在编译时评估,而 readonly 在运行时评估。您还可以在构造函数中为只读变量赋值。
还有一件事。我在上面的评论中没有看到这一点,尽管我可能错过了。您不能创建常量数组。
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 };
不能用常数做到这一点,可以吗?
不同之处在于静态只读字段的值是在运行时设置的,因此可以由包含类修改,而 const 字段的值设置为编译时常量。
在静态只读情况下,只允许包含类修改它
在变量声明中(通过变量初始值设定项) 在静态构造函数中(实例构造函数,如果它不是静态的) 如果在 const 声明中不允许字段的类型,或者当值未知时,通常使用静态只读编译时间。
也允许实例只读字段。
请记住,对于引用类型,在两种情况下(静态和实例),只读修饰符只会阻止您为该字段分配新引用。它特别不会使引用指向的对象不可变。
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,必须将其初始化为编译时常量。为了稍微扩展静态只读情况,包含类只能修改它:
-- 在变量声明中(通过变量初始化器)。
-- 在静态构造函数中(实例构造函数,如果它不是静态的)。
C# .NET 中的 const 关键字
示例:public const string abc = “xyz”;
仅在声明时初始化。值在编译时评估,不能在运行时更改。尝试更改它会导致编译错误。Const 已经是一种静态的了。由于类和结构是在运行时使用 new 关键字初始化的,因此您不能为类或结构设置常量。但是,它必须是整数类型之一。C# .NET 中的只读关键字
示例:public readonly string abc;
可以在声明代码或构造函数代码中初始化。在运行时评估值。可以声明为静态或实例级属性。只读字段可以通过在运行时使用 new 关键字来保存复杂对象。
只读字段可以在声明或类的构造函数中初始化。因此,只读字段可以有不同的值,具体取决于使用的构造函数。
只读成员也可用于运行时常量,如下例所示:
public static readonly uint currentTicks = (uint)DateTime.Now.Ticks;
只读字段不是隐式静态的,因此如果需要,静态关键字可以(必须)显式应用于只读字段。这对于隐式静态的 const 字段是不允许的。
只读成员可以通过在初始化时使用 new 关键字来保存复杂对象。