Search code examples
c#.netcompiler-errors.net-standardout-parameters

Why an Out Parameter can be left unassigned in projects targeting .NET Standard?


I tried the below code in a C# (ClassLibrary) project that targets .NET Standard 2.0 and it compiles successfully, meanwhile it gives an error in another project targeting .NET Core 3.1

private void SetOffset(out TimeSpan offset)
{
    return;
}

The error in .NET Core project is as expected:

CS0177: The out parameter 'offset' must be assigned to before control leaves the current method


Solution

  • That's because if struct contains no fields, it is considered assigned. For example:

    private void SetOffset(out Test offset)
    {
        return;
    }
    
    struct Test {
        void DoSomething() {
    
        }
    }
    

    Compiles just fine in .NET Core 3.1 (and other .NET versions).

    Now, there was (is?) an issue in .NET Standard reference libraries (those libraries basically only contain a "stub" and a "real" library is actually used when code is run) that private fields were not included, so TimeSpan in .NET Standard 2.0 reference library doesn't contain any accessible fields, and so is considered assigned by compiler by the same reason as Test struct above. This issue is discussed in more details here. Actually it might be more complicated that "doesn't contain any fields", because as you can read in the linked issue - some fields might be ignored by compiler in such reference assembly. But in the end result is the same - compiler treats this structure as containing no accessible fields and allows the usage in question.

    Edit removed "accessible": the accessibility of the struct's fields makes no difference (see section 9.4.1 of the C# 8, latest available, specification).