【发布时间】:2012-11-03 09:57:55
【问题描述】:
我今天在创建 struct 来保存一堆数据时遇到了这个问题。这是一个例子:
public struct ExampleStruct
{
public int Value { get; private set; }
public ExampleStruct(int value = 1)
: this()
{
Value = value;
}
}
看起来不错,花花公子。问题是当我尝试使用此构造函数而不指定值并希望对参数使用默认值 1 时:
private static void Main(string[] args)
{
ExampleStruct example1 = new ExampleStruct();
Console.WriteLine(example1.Value);
}
此代码输出0,不输出1。原因是所有结构都有公共的无参数构造函数。所以,就像我在Main 中调用this() 我的显式构造函数一样,同样的事情发生在new ExampleStruct() 实际上调用ExampleStruct() 但没有调用ExampleStruct(int value = 1) 的地方。因为它这样做了,所以它使用int 的默认值 0 作为Value。
更糟糕的是,我的实际代码正在检查 int value = 1 参数是否在构造函数的有效范围内。将此添加到上面的 ExampleStruct(int value = 1) 构造函数中:
if(value < 1 || value > 3)
{
throw new ArgumentException("Value is out of range");
}
因此,就目前而言,默认构造函数实际上创建了一个在我需要它的上下文中无效的对象。任何人都知道我该怎么做:
- A.调用
ExampleStruct(int value = 1)构造函数。 - 乙。修改为
ExampleStruct()构造函数填充默认值的方式。 - C.其他一些建议/选项。
另外,我知道我可以使用这样的字段来代替我的 Value 属性:
public readonly int Value;
但我的理念是私下使用字段,除非它们是 const 或 static。
最后,我使用 struct 而不是 class 的原因是因为这只是一个保存非可变数据的对象,在构造时应完全填充,并在作为参数传递时, 不应该是 null (因为它是作为 struct 值传递的),这是 struct 的设计目的。
【问题讨论】:
-
这不一定是使用
struct的全部理由,您仍然可以使用class完成所有这些操作,然后抛出ArgumentNullException。 MSDN 概述了使用strcut的主要原因:msdn.microsoft.com/en-us/library/ms229017.aspx -
有一天我应该在博客中介绍所有使用结构的疯狂示例!谢谢你!
-
请注意,每次调用都会复制数据,因为它是一个结构......
-
范围不是 1-3,而是范围 0-2,并且有一个属性可以将返回值修改为正确的范围;)
-
@Porges:你可以这样做,但这会很混乱,并且必须有详细的文档。我更喜欢可以为空的初始化字段,而不是在 proeprty 访问器上使用默认值。
标签: c# struct optional-parameters default-constructor