我已经了解了常量和静态只读字段。我们有一些类只包含常量值。它们用于我们系统中的各种事情。所以我想知道我的观察是否正确:

对于所有公开的内容,这些常量值是否总是静态只读的?并且只对内部/受保护/私有值使用const?

你有什么建议?我甚至应该不使用静态只读字段,而应该使用财产吗?


当前回答

这只是对其他答案的补充。我不会重复这些(现在是四年后)。

在某些情况下,常量和非常量具有不同的语义。例如:

const int y = 42;

static void Main()
{
  short x = 42;
  Console.WriteLine(x.Equals(y));
}

打印为True,而:

static readonly int y = 42;

static void Main()
{
  short x = 42;
  Console.WriteLine(x.Equals(y));
}

写入False。

原因是,方法x.Equals有两个重载,一个接受短(System.Int16),另一个接受对象(System.object)。现在的问题是,是一个还是两个都适用于y参数。

当y是编译时常数(文字)(常量)时,如果int是常量,并且C#编译器验证其值是否在short(42是)的范围内,那么从int到short的隐式转换就变得很重要了。请参阅C#语言规范中的隐式常量表达式转换。因此,必须考虑这两种过载。首选重载Equals(short)(任何short都是一个对象,但不是所有对象都是短的)。所以y被转换为short,并使用过载。然后Equals比较两个短的相同值,结果为真。

当y不是常数时,不存在从int到short的隐式转换。这是因为一般来说,int可能太大,无法放入short。(确实存在显式转换,但我没有说Equals((短)y),所以这不相关。)我们看到只有一个重载适用,Equals(对象)重载。所以y被装箱为对象。然后Equals将比较System.Int16和System.Int32,因为运行时类型甚至不一致,这将产生false。

我们得出的结论是,在某些(罕见的)情况下,将常量类型成员更改为静态只读字段(或在可能的情况下,以其他方式)可以更改程序的行为。

其他回答

readonly关键字与const关键字不同。常量字段只能在字段声明处初始化。只读字段可以在声明或构造函数中初始化。因此,只读字段可以具有不同的值,具体取决于所使用的构造函数。此外,虽然const字段是编译时常量,但只读字段可以用于运行时常量

从这个简短而清晰的MSDN参考中。

施工

只能应用于字段。值应在代码编译时。适合在编译代码之前就已经知道的代码中删除神奇的“字符串”、“int/double”、(原始类型)等。编译后,该值将被放置在编译代码的所有使用常量的地方。所以,如果你在很多地方使用了一个巨大的字符串,那么在使它成为常量之前要小心。考虑使用静态只读。

静态只读

静态只读应用于字段/道具,静态可用于方法。(附带说明)当静态应用于方法时,编译的代码不会将“this”参数传递给方法,因此您无法访问对象的实例数据。适用于编译代码后可能更改的值。类似于在应用程序启动等过程中从配置初始化的值。编译代码后,在IL代码中使用ref to值,与使用const相比可能会慢一些,但编译的代码很小

在重构过程中,所有常量都可以安全地转换为静态只读,但反之亦然,正如我们前面所看到的,当一些静态只读变量可以在构造函数中初始化时,转换后的代码可能会中断。

Const、readonly、static readonly-执行类似操作但有重要区别的关键字:

•Const-是一个变量,其值为常量,在编译时赋值。必须为其赋值。默认常量是静态的,我们不能在整个程序中更改常量变量的值。

•只读-意味着我们可以在运行时更改的值,也可以在运行时间分配它,但只能通过非静态构造函数。

•静态只读值​​可以在运行时分配,也可以在编译时分配,并在运行时更改。但该变量的值只能在静态构造函数中更改。并且不能进一步改变。在执行过程中只能更改一次。

您可以在此处找到示例-https://www.c-sharpcorner.com/UploadFile/c210df/difference-between-const-readonly-and-static-readonly-in-C-Sharp/

有一个重要的问题,在上面的答案中没有提到,应该会促使您更喜欢“const”,特别是对于“int”、“string”等基本类型。

常量可以用作属性参数,静态只读字段不能!

Azure函数HttpTrigger,未在属性中使用HttpMethods类

如果微软为Http的GET、POST、DELETE等使用常量就好了。

可以写

[HttpTrigger(AuthorizationLeve.Anonymous,  HttpMethods.Get)] // COMPILE ERROR: static readonly, 

但我不得不求助于

[HttpTrigger(AuthorizationLeve.Anonymous,  "GET")] // STRING

或者使用我自己的常量:

public class HttpConstants
{
    public const string Get = "GET";
}

[HttpTrigger(AuthorizationLeve.Anonymous,  HttpConstants.Get)] // Compile FINE!

Const:Const只是“常量”,它的值是常量,但在编译时是常量。并且必须为其赋值。默认情况下,常量是静态的,我们不能在整个程序中更改常量变量的值。静态只读:静态只读类型变量的值可以在运行时赋值,也可以在编译时赋值,并在运行时更改。但该变量的值只能在静态构造函数中更改。并且不能进一步改变。它只能在运行时更改一次

参考:c-sharpcorner