共用方式為


在 .NET 8.0.100 到 .NET 9.0.100 之後,Roslyn 的重大變更

本檔列出在 .NET 8 一般版本 (.NET SDK 8.0.100 版) 到 .NET 9 一般版本 (.NET SDK 9.0.100 版) 之後,Roslyn 的已知重大變更。

已不再允許記錄結構類型的 InlineArray 屬性。

Visual Studio 2022 17.11版中引進的

[System.Runtime.CompilerServices.InlineArray(10)] // error CS9259: Attribute 'System.Runtime.CompilerServices.InlineArray' cannot be applied to a record struct.
record struct Buffer1()
{
    private int _element0;
}

[System.Runtime.CompilerServices.InlineArray(10)] // error CS9259: Attribute 'System.Runtime.CompilerServices.InlineArray' cannot be applied to a record struct.
record struct Buffer2(int p1)
{
}

反覆運算器在 C# 13 和更新版本中引進安全上下文

Visual Studio 2022 17.11版中引進的

雖然語言規格指出反覆運算器引進安全內容,但 Roslyn 不會在 C# 12 和更低版本中實作該內容。 這在 C# 13 中將因為新功能 而改變,這項功能允許在反覆運算器中使用不安全程式碼。 變更不會中斷正常案例,因為不允許直接在反覆運算器中使用不安全的建構。 不過,它可能會中斷那些以前不安全的環境被繼承到巢狀本地函數的情境,例如:

unsafe class C // unsafe context
{
    System.Collections.Generic.IEnumerable<int> M() // an iterator
    {
        yield return 1;
        local();
        void local()
        {
            int* p = null; // allowed in C# 12; error in C# 13
        }
    }
}

只要將 unsafe 修飾詞新增至本機函式,您就可以解決中斷問題。

C# 13 和更新的集合表達式重大變更與多載解析

使用 C# 13+時,Visual Studio 2022 17.12 版和更新版本中引進的

C# 13 中的集合運算式系結有一些變更。 其中大部分都會將模棱兩可變成成功的編譯,但其中幾個是導致新編譯錯誤或行為中斷性變更的重大變更。 其詳述如下。

空集合表達式不再使用 API 是否為跨度來系結多載

當將空集合表達式提供給多載方法,且沒有明確的元素類型時,我們不再使用 API 是否採用 ReadOnlySpan<T>Span<T> 來判斷是否偏好使用該 API。 例如:

class C
{
    static void M(ReadOnlySpan<int> ros) {}
    static void M(Span<object> s) {}

    static void Main()
    {
        M([]); // C.M(ReadOnlySpan<int>) in C# 12, error in C# 13.
    }
}

精確的元素類型優先於其他所有類型

在 C# 13 中,我們偏好精確的元素類型匹配,檢查來自表達式的類型轉換。 當涉及常數時,這可能會導致行為變更:

class C
{
    static void M1(ReadOnlySpan<byte> ros) {}
    static void M1(Span<int> s) {}

    static void M2(ReadOnlySpan<string> ros) {}
    static void M2(Span<CustomInterpolatedStringHandler> ros) {}

    static void Main()
    {
        M1([1]); // C.M(ReadOnlySpan<byte>) in C# 12, C.M(Span<int>) in C# 13

        M2([$"{1}"]); // C.M(ReadOnlySpan<string>) in C# 12, C.M(Span<CustomInterpolatedStringHandler>) in C# 13
    }
}

已不再允許在未正確宣告DefaultMemberAttribute的情況下宣告索引器。

在 Visual Studio 2022 版本 17.13 中引進

public interface I1
{
    public I1 this[I1 args] { get; } // error CS0656: Missing compiler required member 'System.Reflection.DefaultMemberAttribute..ctor'
}

預設和參數參數會在方法群組自然類型中視為

在 Visual Studio 2022 版本 17.13 中引進

先前編譯程式 非預期地 根據使用預設參數值或 params 陣列時來源中候選項目的順序推斷不同的委派類型。 現在產生不明確錯誤。

using System;

class Program
{
    static void Main()
    {
        var x1 = new Program().Test1; // previously Action<long[]> - now error
        var x2 = new Program().Test2; // previously anonymous void delegate(params long[]) - now error

        x1();
        x2();
    }
}

static class E
{
    static public void Test1(this Program p, long[] a) => Console.Write(a.Length);
    static public void Test1(this object p, params long[] a) => Console.Write(a.Length);

    static public void Test2(this object p, params long[] a) => Console.Write(a.Length);
    static public void Test2(this Program p, long[] a) => Console.Write(a.Length);
}

此外,在 LangVersion=12 或更低版本中,params 修飾詞必須在所有方法中保持一致,以推斷出唯一的委派簽名。 請注意,這不會影響 LangVersion=13 和後續版本,因為 使用了不同的委派推斷算法

var d = new C().M; // previously inferred Action<int[]> - now error CS8917: the delegate type could not be inferred

static class E
{
    public static void M(this C c, params int[] x) { }
}

class C
{
    public void M(int[] x) { }
}

因應措施是使用明確的委派類型,而不是在這些情況下依賴 var 推斷。

dotnet_style_require_accessibility_modifiers 現在一致地應用於介面成員

PR:https://github.com/dotnet/roslyn/pull/76324

在此變更之前,dotnet_style_require_accessibility_modifiers的分析器只會忽略介面成員。 這是因為 C# 一開始完全不允許介面成員的修飾詞,使其一律為公用。

較新版本的語言放寬了此限制,允許使用者在介面成員上提供可見性修飾詞,包括冗餘的 public 修飾詞。

分析器已更新,現在在介面成員上也強制要求這個選項的值。 值的意義如下:

  1. never。 分析器不會進行分析。 允許冗餘修飾詞用於所有成員。
  2. always。 所有成員(包括介面成員)都必須使用冗餘修飾詞。 例如:類別成員上的 private 修飾詞,以及介面成員上的 public 修飾詞。 如果您覺得所有成員都應該明確陳述其存取範圍,則可以使用此選項。
  3. for_non_interface_members。 介面成員不 但不允許介面成員的所有成員 需要備援修飾詞。 例如:私人類別的成員將需要 private。 不過,不允許公用介面成員具有多餘的 public 修飾詞。 這符合在語言允許在介面成員上使用修飾符之前所存在的標準的修飾符方法。
  4. omit_if_default。 不允許備援修飾詞。 例如,不允許私用類別成員使用 private,而且不允許使用 public公用介面成員。 如果您覺得在符合語言默認選擇的內容時,重新設定輔助功能是多餘的,而且應該不允許使用此選項。