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

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

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


当前回答

需要注意的几个相关事项:

常量int a

必须初始化。初始化必须在编译时进行。

只读int a

可以使用默认值,而无需初始化。初始化可以在运行时完成(编辑:仅在构造函数内)。

其他回答

Const:常量变量值必须与声明一起定义,之后它不会改变。这在编译时有一个值。

ReadOnly:我们可以在声明时定义只读变量值,也可以在运行时使用构造函数。没有类实例,只读变量无法访问。

静态只读:我们可以在声明时定义静态只读变量值,也可以仅通过静态构造函数,但不能使用任何其他构造函数。我们还可以在不创建类实例(作为静态变量)的情况下访问这些变量。

如果我们必须在不同的程序集中使用变量,静态只读将是更好的选择。请在以下博客文章中查看详细信息:

Const Strings——一种非常方便的射击自己脚的方式

有一个重要的问题,在上面的答案中没有提到,应该会促使您更喜欢“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!

C#.Net中的常量和静态只读字段之间有一个微小的区别

const必须在编译时用值初始化。

const在默认情况下是静态的,需要用常量值初始化,以后不能修改。它不能与所有数据类型一起使用。对于ex-DateTime。它不能与DateTime数据类型一起使用。

public const DateTime dt = DateTime.Today;  //throws compilation error
public const string Name = string.Empty;    //throws compilation error
public static readonly string Name = string.Empty; //No error, legal

只读可以声明为静态,但不是必需的。无需在声明时进行初始化。它的值可以使用构造函数赋值或更改一次。所以,有可能更改只读字段的值一次(不管它是静态的还是非静态的),这在const中是不可能的。

另外一个我不相信的区别是上面提到的:

常量和静态只读值不会在Visual Studio IDE中应用CodeLens。

static只获取财产,但会将CodeLens应用于这些属性。

我认为添加CodeLens非常有价值。

注意:当前正在使用Visual Studio 2022。

如果可以提供编译时间常数,请使用const:

private const int Total = 5;

如果需要在运行时计算值,请使用静态只读:

private static readonly int GripKey = Animator.StringToHash("Grip");

这将导致编译错误,因为在编译时不可能获得该值。

private const int GripKey = Animator.StringToHash("Grip");