Skip to content

Latest commit

 

History

History
79 lines (69 loc) · 4.29 KB

Compiler Breaking Changes - DotNet 5.md

File metadata and controls

79 lines (69 loc) · 4.29 KB

This document lists known breaking changes in Roslyn in C# 9.0 which will be introduced with .NET 5 (Visual Studio 2019 version 16.8).

  1. Beginning with C# 9.0, when you switch on a value of type byte or sbyte, the compiler tracks which values have been handled and which have not. Technically, we do so for all numeric types, but in practice it is only a breaking change for the types byte and sbyte. For example, the following program contains a switch statement that explicitly handles all of the possible values of the switch's controlling expression

    int M(byte b)
    {
        switch (b)
        {
            case 0: case 1: case 2: ...
                return 0;
        }
        return 1;
    }

    Since it returns from the method M on every value of the input, the following statement (return 1;) is considered not to be reachable and will produce a warning for unreachable code. Previously, the compiler did not analyze the set of values for completeness, and the following statement was considered reachable. This code compiles without warnings in C# 8.0 but will produce a warning in C# 9.0.

    Similarly, a switch expression that explicitly handles all values of an input of type byte or sbyte is considered to be complete. For example, the following program

    int M(byte b)
    {
        return b switch
        {
            0 => 0, 1 => 0, 2 => 0, ... byte.MaxValue => 0,
        };
    }

    Would produce a warning when compiled in C# 8.0 (the switch expression does not handle all values of its input), but produces no warning in C# 9.0. Conversely, adding a fallback branch to it would suppress the warning in C# 8.0, but cause an error in C# 9.0 (the case is handled by previous cases):

    int M(byte b)
    {
        return b switch
        {
            0 => 0, 1 => 0, 2 => 0, ... byte.MaxValue => 0,
            _ => 1 // error in C# 9.0
        };
    }
  2. not as a type in a pattern not permitted in C# 9.0 In C# 9.0 we introduce a not pattern that negates the following pattern:

        bool IsNull(object o) => o is not null;

    We recommend the pattern not null as the most clear way to check if a value is not null.

    Because a pattern in C# 9.0 can start with not as part of the pattern, we no longer consider a pattern that starts with not to be referencing a type named not. The expression o is not x used to declare a variable x of type not. Now, it checks that the input o is not the same as the constant named x.

  3. and and or are not permitted as a pattern designator in C# 9.0 In C# 9.0, we introduce and and or pattern combinators that combine other patterns:

       bool IsSmall(int i) => o is 0 or 1 or 2;

    We also introduce type patterns so that you do not have to have an identifier naming the variable you are declaring:

        bool IsSignedIntegral(object o) =>
            o is sbyte or short or int or long;

    Because the and and or combinators can follow a type pattern, the compiler interprets them as part of the pattern combinator rather than an identifier for the declaration pattern. Consequently, it is an error to use or or and as pattern variable identifiers starting with C# 9.0.

  4. #44841 In C# 9 and onwards the language views ambiguities between the record identifier as being either a type syntax or a record declaration as choosing the record declaration. The following examples will now be record declarations:

    abstract class C
    {
        record R2() { }
        abstract record R3();
    }
  5. The fix for #44067 generates correct (different) code. In certain cases the compiler used to generate code whose behavior was ambiguous according to the CLR's specification. The compiler used to produce the warning CS1957 in those cases. The compiler now generates correct unambiguous code rather than reporting CS1957. Because it is possible that the runtime behavior of a program will change due to the change in our code generation strategy, this could be a breaking change. If your program did not elicit the warning CS1957 before then this does not affect your code.