【问题标题】:Initialize Struct with parameterless constructor使用无参数构造函数初始化 Struct
【发布时间】:2019-10-24 13:52:24
【问题描述】:

我(第一次)尝试使用结构,但遇到了一个小问题,我不知道如何解决。

public struct TextSelect<TEnum> where TEnum : Enum
{
    public TextSelect(string input = "")
    {
        Input = input;
        Values = EnumDto.ToList<TEnum>();
    }

    public string Input { get; set; }
    public IEnumerable<EnumDto> Values { get; }
}

public TextSelect<IndustryType> Industry = new TextSelect<IndustryType>();

问题与无参数构造函数有关。

我想在结构体实例化的时候初始化Values属性,但是TEnum是一个类型,不是实例值,所以不算参数。

因此,如果构造函数没有参数,我会收到编译器警告。

如果我添加一个可选值“输入”,我可以欺骗编译器并且警告消失,但构造函数仍然不会触发(可能是因为它是空的)。

除了将其更改为类,还有其他解决方法吗?

感谢所有建议。

【问题讨论】:

  • 你能检查一下这个解决方法吗? stackoverflow.com/a/433233/2770248
  • 为什么要它成为一个结构体?很少有结构有意义的情况,而您的似乎不是其中之一。结构体可以存储在堆栈中,但由于您的结构体包含引用类型作为属性(IEnumerable&lt;T&gt;string),因此无论如何都涉及到堆。
  • 你在这个struct 上有一个set 的事实已经告诉我你在这里非常危险。你为什么要把它写成struct
  • "但是构造函数仍然没有触发" - 使用new TextSelect()(或default),隐式默认初始化器(只是一个“全零”blit)将比使用更好的匹配可选参数,因此将使用默认初始化器。
  • 感谢您的意见。当 Marc Gravell 告诉我“你在非常危险的水中”时,我知道这是一个糟糕的方法。我会放弃它!

标签: c# struct


【解决方案1】:

对于无参数构造函数 - 没有办法让它触发。在 C# 结构中,字段总是使用默认值初始化。

虽然有一些解决方法。如果您真的致力于将其保留为 struct 并希望该字段默认返回不同的值,我建议将 Values 转换为完整属性并在未初始化字段的情况下返回所需的值:

private IEnumerable<EnumDto> _values;
public IEnumerable<EnumDto> Values => _values ?? Array.Empty<EnumDto>();

话虽如此,对结构这样做并不是最好的做法。

编辑:通过@Marc Gravell 的建议更改了解决方案。

【讨论】:

  • 观察:这将创建一个新列表每次访问属性时(当该字段为空时) - 不是一个好主意; =&gt; _values ?? Array.Empty&lt;EnumDto&gt;(); 会好很多
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多