如何在C#中将类实例声明为常量?
我需要实施以下措施:如何在C#中将类实例声明为常量?,c#,.net,constants,C#,.net,Constants,我需要实施以下措施: static class MyStaticClass { public const TimeSpan theTime = new TimeSpan(13, 0, 0); public static bool IsTooLate(DateTime dt) { return dt.TimeOfDay >= theTime; } } 时间是一个常数(严重的:-),就像π是一样,在我的例子中,从设置中读取它是没有意义的。我希望
static class MyStaticClass
{
public const TimeSpan theTime = new TimeSpan(13, 0, 0);
public static bool IsTooLate(DateTime dt)
{
return dt.TimeOfDay >= theTime;
}
}
时间
是一个常数(严重的:-),就像π
是一样,在我的例子中,从设置中读取它是没有意义的。我希望它被初始化一次,并且永远不会改变
但是C#似乎不允许一个常量由一个函数(构造函数就是这样)初始化。如何克服这个问题?常量必须是编译时常量,编译器不能在编译时计算构造函数。使用和使用
一般来说,我更喜欢在构造函数中初始化,而不是通过直接赋值,因为您可以控制初始化的顺序。使用
只读
而不是常量
可以初始化,并且在初始化之后不会修改。这就是你要找的吗
public static readonly TimeSpan theTime = new TimeSpan(13, 0, 0);
代码示例:
static class MyStaticClass
{
static readonly TimeSpan theTime;
static MyStaticClass()
{
theTime = new TimeSpan(13, 0, 0);
}
}
发件人:
常数必须是值类型(sbyte,
字节,短,ushort,int,uint,长,
ulong、char、float、double、decimal、,
或bool)、枚举、字符串
文本,或对null的引用
如果要创建对象,则必须以静态只读方式创建:
static class MyStaticClass
{
public static readonly TimeSpan theTime = new TimeSpan(13, 0, 0);
public static bool IsTooLate(DateTime dt)
{
return dt.TimeOfDay >= theTime;
}
}
C#的const
与C++的const
含义不同。在C#中,const
基本上用于定义文本的别名(因此只能用文本初始化)readonly更接近您想要的,但请记住,它只影响赋值运算符(除非对象的类具有不可变的语义,否则对象实际上不是常量)。您可以使用:
当字段声明包含只读修饰符时,指定给
声明引入的字段只能作为
声明或在同一类的构造函数中
示例(从链接的MSDN页面复制):
常量表示其值永远不能更改的静态成员。这意味着在编译时定义了一个常量值。
用以下语句:
public const TimeSpan theTime = new TimeSpan(13, 0, 0);
违反了常量字段的两个公理:
- 只有C#内置类型(不包括System.Object)可以声明为常量。
- 必须在编译时求值
问题中使用了TimeSpan类型,它不是内置(预定义)类型。这意味着csc.exe编译器无法识别它。
如果使用内置C#类型(例如字符串),并且希望使用编译时值初始化常量成员,则仍然会出现错误:
e、 g.
public const string MyNumber = SetMyString();
private string SetMyString()
{
return "test";
}
解决您可以通过以下方式声明成员的问题:
如果要在运行时仅声明一次字段,请使用修饰符:
public static readonly string MyNumber = SetMyString();
private static string SetMyString()
{
return "test";
}
时间
也应该是静态的。所以只有一个,上面的例子可以编译。为什么是构造函数?仅将成员描述为公共静态只读TimeSpan theTime=new TimeSpan(13,0,0)似乎有效(至少没有编译错误)。@pickypg-抱歉,我的错误-修复@伊万-我补充了一条评论。我个人不喜欢直接初始化,因为你需要搜索一个类来找出初始化的地方。将初始化始终放在构造函数中是一致的,您可以很容易地看到类的初始状态是什么。您还可以直接控制初始化的顺序。在一个普通的静态类中,可能没有太大的区别。但好的实践是好的实践,尤其是在边缘情况下。使用ctor进行成员初始化的最大好处是,您有机会在引发异常的上下文中捕获和处理异常。我在自己的代码中使用了这一点,但我的肛门保持个性知道,每次我这样做,我的应用程序的记忆中都有一个长期存在的对象。我有一个长时间运行的应用程序,它已经占用了太多的内存,这让我很烦恼。我希望有一个TimeSpan文本可以编译到我的代码中。另一种方法是使用常量int,将我的TimeSpan值转换为毫秒。。。但是math.Readonly并不是const的正确类比。相反,您可能希望使用静态只读,正如詹姆斯在下面的回答中提到的那样。@ashelvey我在寻找一种像OP一样的固定方法时找到了这个页面。在我的情况下,只读不起作用,静态也不起作用。我想在类属性的属性中使用它,这意味着我需要一个常量。(我没有投你反对票,因为这不太可能,但这是你得到一些的一个可能原因。)readonly static不适用于开关情况和默认参数。我们仍然需要常量。值得一提的是,静态只读
字段可以通过反射进行更改,而常量
不能。
public const string MyNumber = SetMyString();
private string SetMyString()
{
return "test";
}
static readonly
public static readonly string MyNumber = SetMyString();
private static string SetMyString()
{
return "test";
}