【发布时间】:2011-02-22 13:00:35
【问题描述】:
我正在尝试编写以下代码:
public const Size ImageSize = new Size() { Width = 28, Height = 28 };
但我得到Width 和Height 是只读的错误。
推荐的方法是什么?
【问题讨论】:
标签: c# .net constants readonly
我正在尝试编写以下代码:
public const Size ImageSize = new Size() { Width = 28, Height = 28 };
但我得到Width 和Height 是只读的错误。
推荐的方法是什么?
【问题讨论】:
标签: c# .net constants readonly
const 仅限于编译器可以直接编写为 IL 的原语。 readonly 在这里就足够了 如果 Size 被视为不可变的,即
public static readonly Size ImageSize = new Size(28,28);
请注意,如果Size 是可变的struct,则可能会发生不好的事情;我会推荐一个属性而不是一个字段来防止一些令人困惑的副作用。
【讨论】:
readonly 在这种情况下会处理这个问题(您不能更改标记为readonly 的struct 中的字段;编译器不允许您这样做)。至于Size 是否是可变结构:这取决于我们在谈论哪个Size:OP 没有引用命名空间,并且有几个 Size 类型在BCL,或者您当然可以定义自己的。
根本问题是您不能将System.Drawing.Size 类型的对象声明为const。这表明该符号将在编译时用常量的值替换。
相反,您应该使用readonly。这也是一个“常量”值,因为一旦构造函数运行就无法修改它,但是对象是在运行时而不是编译时创建的。
以下代码编译得很好:
public static readonly Size ImageSize = new Size() { Width = 28, Height = 28 };
【讨论】:
public static readonly Size ImageSize = new Size(28,28);
【讨论】:
你必须这样做:
public readonly Size ImageSize = new Size(28, 28);
将实例设为只读以防止其被更改,因为您无法将 Size 创建为常量。
来自文档:
常量表达式是可以在编译时完全计算的表达式。因此,引用类型常量的唯一可能值是 string 和 null。
【讨论】:
你正在编写的代码:
public const Size ImageSize = new Size() { Width = 28, Height = 28 };
其实编译下来和这个一样:
public const Size ImageSize = new Size();
ImageSize.Width = 28;
ImageSize.Height = 28;
您使用的版本,称为对象初始化器,只是上面后一个版本的语法简写。两者在逻辑上是相同的。在后一个版本中,您可以看到为什么它会给您错误,您无法在 const 声明后设置属性。
更重要的是,我不确定您是否甚至可以使用像 const 这样的引用类型。我不确定,因为我不能说我曾经尝试过。你可以试试readonly。虽然您可能会遇到相同或相似的问题。
Size 是否有一个可以使用参数调用的构造函数,而不是使用对象初始值设定项?
【讨论】:
Size 当然确实有一个以宽度和高度作为参数的构造函数。这仍然无法解决您的根本问题,但仍然值得了解。
你可以使用:
public static readonly Size ImageSize = new Size(28, 28);
它实际上不是一个const,但初始化后不会改变。
【讨论】:
您需要使用一个以宽度和高度为参数的构造函数。
此外,表达式必须在编译期间完全可评估。这可能不适用于您的 Size 类型(不知道它是哪一种)。如果是这样(例如使用System.Drawing.Size),您可以考虑使用readonly 而不是const。
【讨论】: