Search code examples
c#language-specifications

Why Can't I Specify The Size Of The Array Returned From A C# Function?


I know that the following C# code will not compile:

int[10] TestFixedArrayReturn(int n)
{
   return new int[10]{n, n, n, n, n, n, n, n, n, n};
}
void TestCall()
{
   int[10] result = TestFixedArrayReturn(1);
}

In order to get it to compile, I need to remove the array size from the function declaration (as well as the declaration of the result variable) like so:

int[] TestFixedArrayReturn(int n)
{
   return new int[10]{n, n, n, n, n, n, n, n, n, n};
}
void TestCall()
{
   int[] result = TestFixedArrayReturn(1);
}

I'm just wondering--why is that I cannot specify the size of the array of ints which will get returned? I take it what's getting passed back is actually a reference to the array (that'd be my guess anyway) but why can't I specify the size of the array being returned? Wouldn't this allow the compiler to check my code more closely for correctness?


Solution

  • The simple answer I think, is that in .net:

    1. Functions return instances of a type
    2. Therefore, functions are declared as having a return type
    3. Arrays are a single type (Class) in .net, so that they can interoperate
    4. Conversely, however, this means that arrays of different fixed sizes do not have different Types, just different instance attributes.
    5. Which means that functions cannot be defined to return arrays of a specific fixed size because the length of an array is not part of its type specification, but rather part of its instance settings/attributes.

    For variables, this seems like it can be done in the type declaration of variables, but it is actually part of the instance initialization specs there, even though syntactically it looks like it’s part of the type declaration. This was probably retained for style compatibility reasons with older languages like C, where things worked much differently under the hood.

    For functions, however, the return object is not initialized where it is declared (in the function declaration) but rather procedurally in the body of the function itself. So allowing instance attributes to be set in the function declaration could have caused all kinds of conflicts and edge cases that would need to be checked either by the compiler or at run-time, neither of which was probably seen as being worth the very minimal gain.