Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Visual Studio Type a Newly Minted Array as Nullable?

I'm writing a function with a generic type TVal. I wrote this line:

var zeroBased = new TVal[size];

And then in Visual Studio (VS) I used alt+enter to replace var with an explicit type. Here's what I got:

TVal[]? zeroBased = new TVal[size];

I was surprised to find the ? operator, indicating that the type might be nullable. I thought that I'd be safe enough assuming the type is never null when created with new, and could have just done:

TVal[] zeroBased = new TVal[size];

Is there a scenario where instantiating a new array in C# can give you back null?

Note: the code seems to compile fine without the ?, I'm just intrigued by VS's suggestion...

Minimal Verifiable Example

Open Visual Studio, same version as specified below, create a new project, enable nullable types as per the VS Project File Contents below, create a new class, and pop in this function:

public void Test<T>(int size)
{
  var tArr = new T[size];
}

The select the var and hit alt+enter, and choose to replace var with explicit type. If the behaviour is the same as the one I experienced, you'll get:

public void Test<T>(int size)
{
  T[]? tArr = new T[size];
}

Visual Studio Project File Contents

We're using C# 8 for this project and we've enabled Nullables:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <Nullable>enable</Nullable>
    <LangVersion>8.0</LangVersion>
    <WarningsAsErrors>CS8600;CS8602;CS8603</WarningsAsErrors>
    <TargetFramework>netstandard2.0</TargetFramework>
    <OutputType>Library</OutputType>
    <Version>1.0.0.9</Version>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
    <PackageReference Include="System.Dynamic.Runtime" Version="4.3.0" />
  </ItemGroup>

</Project>

Visual Studio Version Info (just bits that seemed important to this Q)

Microsoft Visual Studio Community 2019 Version 16.6.1 VisualStudio.16.Release/16.6.1+30128.74 Microsoft .NET Framework Version 4.7.03062

Installed Version: Community

C# Tools 3.6.0-4.20251.5+910223b64f108fcf039012e0849befb46ace6e66 C# components used in the IDE. Depending on your project type and settings, a different version of the compiler may be used.

like image 816
Colm Bhandal Avatar asked Jun 08 '20 17:06

Colm Bhandal


People also ask

What is the nullable modifier?

The nullable type modifier (?) is included on the variable in a variable declaration in which the array modifiers (parentheses) are included on the specified variable type.

Are C# objects Nullable?

In C#, the compiler does not allow you to assign a null value to a variable. So, C# 2.0 provides a special feature to assign a null value to a variable that is known as the Nullable type. The Nullable type allows you to assign a null value to a variable.

What is NotNull in C#?

NotNull: A nullable field, parameter, property, or return value will never be null. MaybeNullWhen: A non-nullable argument may be null when the method returns the specified bool value. NotNullWhen: A nullable argument won't be null when the method returns the specified bool value.


1 Answers

I would like to extend an existing answer by adding some links

C# specification proposal says:

nullable implicitly typed local variables

var infers an annotated type for reference types. For instance, in var s = ""; the var is inferred as string?.

It means that var for reference types infers a nullable reference type. This works if nullable context is enabled either using project file or #nullable pragma.

This behavior was discussed in this LDM and implemented in this issue.

This is a reason for making var infer a nullable reference type:

At this point we've seen a large amount of code that requires people spell out the type instead of using var, because code may assign null later.

like image 167
Iliar Turdushev Avatar answered Dec 02 '22 21:12

Iliar Turdushev