我阅读了与此主题相关的所有问题,并且它们都说明了为什么struct
上的默认构造函数在C#中不可用的原因,但我还没有找到任何建议采取一般行动的人面对这种情况。
显而易见的解决方案是简单地将struct
转换为class
并处理后果。
还有其他选项可以将其保留为struct
吗?
我使用我们的一个内部商务API对象遇到了这种情况。设计者将它从class
转换为struct
,现在默认构造函数(之前是私有的)使对象处于无效状态。
我认为如果我们要将对象保持为struct
,应该引入一种检查状态有效性的机制(类似于IsValid
属性)。我遇到了很多阻力,并解释“使用API的人不应该使用默认构造函数”,这一评论肯定引起了我的注意。 (注意:有问题的对象是通过静态工厂方法“正确”构造的,而所有其他构造函数都是internal
。)
在这种情况下,每个人都只是简单地将他们的struct
转换为class
而没有经过深思熟虑吗?
修改:我想看到一些关于如何将此类对象保留为struct
的建议 - 上面讨论的对象更适合作为struct
而非class
1}}。
答案 0 :(得分:4)
对于struct
,您可以设计类型,以便默认构造的实例(字段全为零)是有效状态。你没有[不会]在没有充分理由的情况下任意使用struct
而不是class
- 使用不可变引用类型没有任何问题。
我的建议:
struct
的原因是有效的([真实]分析器显示由于非常轻量级的对象的大量分配导致的重大性能问题。)struct
(私有嵌套类型)。这样,您就可以轻松记录并验证对约束类型要求的正确使用。答案 1 :(得分:1)
这样做的原因是CLR特别处理了一个struct(System.ValueType的一个实例):它被初始化,所有字段都是0(或默认值)。你甚至不需要创建一个 - 只需声明它。这就是需要默认构造函数的原因。
你可以通过两种方式解决这个问题:
将结构体更改为类可能会产生一些非常微妙的结果(在多线程环境中更多地出现在内存使用和对象标识方面),并且对于未初始化的对象,非如此微妙但很难调试NullReferenceExceptions。 / p>
答案 2 :(得分:0)
以下表达式说明了无法定义默认构造函数的原因:
new MyStruct[1000];
这里有3个选项
.NET对结构体和类执行相同的操作:字段和数组元素用零标记。这也使结构和类之间的行为更加一致,并且没有不安全的代码。它还允许.NET框架不专门化new byte[1000]
。
这是结构.NET需要的默认构造函数并自行处理:将所有字节清零。
现在,为了解决这个问题,你有几个选择:
HasValue
上的Nullable
)。