在 C# 中,调整数组大小(在这种情况下增加其大小)会使用默认值初始化新段——这可靠吗?

Posted

技术标签:

【中文标题】在 C# 中,调整数组大小(在这种情况下增加其大小)会使用默认值初始化新段——这可靠吗?【英文标题】:In C# resizing an array (increasing its size in this case) initializes the new segment with default values – is this reliable? 【发布时间】:2019-12-28 00:28:57 【问题描述】:

在 C# 中调整数组大小(在这种情况下增加其大小)会使用默认值初始化新段——这可靠吗?

Array.Resize(ref bytes, bytes.Length + extra);

我确实看到了默认值(字节数组为 0),但是否可以安全地将其作为所有基本类型的标准行为?在我的应用程序中,每秒保存一次是一件大事,因此我认为如果默认情况下新添加的段已经可用,我可以避免不必要的循环来初始化新添加的段。 Microsoft .NET 文档没有明确说明这一事实:https://docs.microsoft.com/en-us/dotnet/api/system.array.resize?view=netframework-4.8 尽管示例暗示了这种行为。

【问题讨论】:

可以安全地假设元素将使用 default(T) 进行初始化 【参考方案1】:

是的,它是可靠的。一种看待它的方式 - 如果新的数组元素不包含默认值,它们将包含什么?该方法不会构成值。

并不是我通常为框架代码编写单元测试,但这是测试预期行为的一种简单方法,尤其是在文档让我们不确定的情况下。

[TestMethod]
public void Resizing_array_appends_default_values()

    var dates = new DateTime[] DateTime.Now;
    Array.Resize(ref dates, dates.Length + 1);
    Assert.AreEqual(dates.Last(), default(DateTime));

    var strings = new string[]  "x" ;
    Array.Resize(ref strings, strings.Length + 1);
    Assert.IsNull(strings.Last());

    var objects = new object[]  1, "x" ;
    Array.Resize(ref objects, objects.Length + 1);
    Assert.IsNull(objects.Last());

不用说我会在运行它之后丢弃这个单元测试。我不会犯的。

【讨论】:

【参考方案2】:

是的,您可以信赖它。从文档(强调我的):

这个方法分配一个指定大小的新数组,将旧数组中的元素复制到新数组中,然后用新数组替换旧数组。数组必须是一维数组。

分配一个新数组保证用默认值填充它(实际上“将所有位设置为 0”),所以如果我们相信描述,整个Array.Resize 操作的结果确实会为所有元素提供默认值尚未从旧数组中复制。

【讨论】:

只是对新数组的补充,它由 ECMA-334 C# 标准 ch.12.7.11.5 : All elements of the new array instance are initialized to their default values 保证 @Renat 这确实很令人欣慰!

以上是关于在 C# 中,调整数组大小(在这种情况下增加其大小)会使用默认值初始化新段——这可靠吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何在不缩放其内容的情况下调整 opengl 视口大小

在不调整大小或重绘的情况下扩展 UIView

c#在panel中动态增加控件时怎样自动调整panel的行列大小

计算用于调整大小的图像大小比率

调整JScrollPane大小的最佳实践

在启用自动布局的情况下调整 swift/xcode 中的按钮大小