C# - 调用具有所有默认参数的结构构造函数

2024-02-21

今天创建的时候遇到了这个问题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。原因是所有结构都有公共无参数构造函数。所以,就像我打电话的方式this()我的显式构造函数,在Main,同样的事情发生在哪里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)构造函数。
  • B. 修改默认值的填充方式ExampleStruct()构造函数。
  • C. 一些其他建议/选项。

另外,我知道我可以使用这样的字段来代替我的Value财产:

public readonly int Value;

但我的理念是私下使用字段,除非它们是const or static.

最后,我使用的原因struct代替class是因为这只是一个保存不可变数据的对象,应该在构造时完全填充,并且当作为参数传递时,不应该能够null(因为它是按值传递的struct),这就是结构体的设计目的。


事实上,MSDN 有一些很好的指导struct

考虑定义结构而不是类,如果 类型较小且通常寿命较短或通常嵌入 其他物体。

除非类型具有以下所有内容,否则不要定义结构 特征:

它在逻辑上表示单个值,类似于原始类型 (整数、双精度数等)。

它的实例大小小于 16 字节。

它是不可改变的。

它不必经常装箱。

请注意,它们是考虑因素考虑到 a struct,而且它从来都不是“这个should始终是一个结构”。这是因为选择使用struct可能会对性能和使用产生影响(正面和负面),应谨慎选择。

特别注意他们不推荐struct对于> 16字节的东西(那么复制的成本变得比复制引用更昂贵)。

现在,对于您的情况,除了创建一个工厂来生成一个工厂之外,确实没有什么好的方法可以做到这一点struct为您处于默认状态或执行某种操作trick在你的财产中欺骗它在第一次使用时初始化。

请记住,一个struct应该这样工作new X() == default(X),即新建一个struct将包含该字段所有字段的默认值struct。这是非常明显的,因为 C# 将not让您为 a 定义一个无参数构造函数struct,尽管奇怪的是它们允许默认所有参数而不发出警告。

因此,我实际上建议你坚持使用class并使其不可变,然后检查null关于它被传递到的方法。

public class ExampleClass
{
    // have property expose the "default" if not yet set
    public int Value { get; private set; }

    // remove default, doesn't work
    public ExampleStruct(int value)
    {
        Value = value;
    }
}

However,如果你绝对must have a struct出于其他原因 - 但请考虑以下费用struct例如复制等 - 你可以这样做:

public struct ExampleStruct
{
    private int? _value;

    // have property expose the "default" if not yet set
    public int Value
    {
        get { return _value ?? 1; }
    }

    // remove default, doesn't work
    public ExampleStruct(int value)
        : this()
    {
        _value = value;
    }
}

请注意,默认情况下,Nullable<int>null(那是,HasValue == false),因此如果这是 true,我们还没有设置它,并且可以使用空合并运算符返回我们的默认值1反而。要是我们did在构造函数中设置它,它将是非空的并取该值......

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C# - 调用具有所有默认参数的结构构造函数 的相关文章

随机推荐