Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In C# resizing an array (increasing its size in this case) initializes the new segment with default values – is this reliable?

In C# resizing an array (increasing its size in this case) initializes the new segment with default values – is this reliable?

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

I do see the default values (0 for byte arrays), but is it possible to safely take that as the standard behavior for all base types? In my application saving every second is a big deal, hence thought I could avoid unnecessary loop to initialize the newly added segment if it is already available by default. Microsoft .NET document doesn’t explicitly state this fact: https://learn.microsoft.com/en-us/dotnet/api/system.array.resize?view=netframework-4.8 although the examples kind of hint to that behavior.

like image 943
Noble Avatar asked Aug 22 '19 16:08

Noble


Video Answer


2 Answers

Yes, you can rely on that. From the documentation (emphasis mine):

This method allocates a new array with the specified size, copies elements from the old array to the new one, and then replaces the old array with the new one. array must be a one-dimensional array.

Allocating a new array is guaranteed to populate it with default values (effectively "set all bits to 0"), so if we trust the description, the result of the overall Array.Resize operation would indeed have default values for all elements which haven't been copied from the old array.

like image 147
Jon Skeet Avatar answered Nov 14 '22 21:11

Jon Skeet


Yes, it is reliable. One way of looking at it - if the new array elements didn't contain the default value, what would they contain? The method isn't going to make up values.

Not that I normally write unit tests for framework code, but it's an easy way to test expected behavior, especially if the documentation leaves us uncertain.

[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());
}

It goes without saying that I would discard this unit test after running it. I wouldn't commit it.

like image 32
Scott Hannen Avatar answered Nov 14 '22 22:11

Scott Hannen