Bagikan melalui


Apa yang baru di C# 13

C# 13 menyertakan fitur baru berikut. Anda dapat mencoba fitur-fitur ini menggunakan versi Visual Studio 2022 terbaru atau .NET 9 SDK:

Dimulai dengan Visual Studio 17.12, C# 13 menyertakan field kata kunci kontekstual sebagai fitur pratinjau.

C# 13 didukung pada .NET 9. Untuk informasi selengkapnya, lihat Penerapan versi bahasa C#.

Anda dapat mengunduh .NET 9 SDK terbaru dari halaman unduhan .NET. Anda juga dapat mengunduh Visual Studio 2022, yang mencakup .NET 9 SDK.

Anda dapat menemukan perubahan signifikan yang diperkenalkan di C# 13 di artikel kami tentang perubahan yang memengaruhi.

Nota

Kami tertarik dengan umpan balik Anda tentang fitur-fitur ini. Jika Anda menemukan masalah dengan salah satu fitur baru ini, buat masalah baru di repositori dotnet/roslyn .

koleksi params

Pengubah params tidak terbatas pada jenis array. Anda sekarang dapat menggunakan params dengan jenis koleksi yang dikenali, termasuk System.Span<T>, System.ReadOnlySpan<T>, dan jenis yang mengimplementasikan System.Collections.Generic.IEnumerable<T> dan memiliki metode Add. Selain jenis beton, antarmuka System.Collections.Generic.IEnumerable<T>, , System.Collections.Generic.IReadOnlyCollection<T>System.Collections.Generic.IReadOnlyList<T>, System.Collections.Generic.ICollection<T>, dan System.Collections.Generic.IList<T> juga dapat digunakan.

Ketika jenis antarmuka digunakan, pengkompilasi mensintesis penyimpanan untuk argumen yang disediakan. Anda dapat mempelajari lebih lanjut dalam spesifikasi fitur mengenai params koleksi.

Misalnya, deklarasi metode dapat mendeklarasikan rentang sebagai params parameter:

public void Concat<T>(params ReadOnlySpan<T> items)
{
    for (int i = 0; i < items.Length; i++)
    {
        Console.Write(items[i]);
        Console.Write(" ");
    }
    Console.WriteLine();
}

Objek kunci baru

Runtime .NET 9 mencakup jenis baru untuk sinkronisasi thread, yaitu jenis System.Threading.Lock. Jenis ini memberikan sinkronisasi utas yang lebih baik melalui API-nya. Metode Lock.EnterScope() memasuki cakupan eksklusif. ref struct yang dikembalikan dari itu mendukung pola Dispose() untuk keluar dari cakupan eksklusif.

Pernyataan C# lock mengenali apakah target kunci adalah Lock objek. Jika demikian, api menggunakan API yang diperbarui, bukan API tradisional menggunakan System.Threading.Monitor. Kompilator juga mengenali apakah Anda mengonversi Lock objek ke jenis lain dan kode berbasis Monitor akan dihasilkan. Anda dapat membaca selengkapnya dalam spesifikasi fitur untuk objek kunci baru.

Fitur ini memungkinkan Anda mendapatkan manfaat dari jenis pustaka baru dengan mengubah jenis objek yang Anda lock. Tidak ada kode lain yang perlu diubah.

Urutan escape baru

Anda dapat menggunakan \e sebagai urutan escape literal karakter untuk ESCAPE karakter, Unicode U+001B. Sebelumnya, Anda menggunakan \u001b atau \x1b. Penggunaan \x1b tidak disarankan karena jika karakter berikutnya berikut adalah 1b digit heksadesimal yang valid, karakter tersebut menjadi bagian dari urutan escape.

Jenis alami dari grup metode

Fitur ini membuat pengoptimalan kecil untuk resolusi kelebihan beban yang melibatkan grup metode. Grup metode adalah metode dan semua kelebihan beban dengan nama yang sama. Perilaku sebelumnya adalah bagi pengkompilasi untuk membangun serangkaian lengkap metode kandidat untuk grup metode. Jika jenis alami diperlukan, jenis alami ditentukan dari set lengkap metode kandidat.

Perilaku baru adalah memangkas kelompok metode kandidat di setiap cakupan, menyingkirkan metode kandidat yang tidak relevan. Biasanya, metode yang dihapus adalah metode generik dengan aritas yang salah, atau batasan yang tidak terpenuhi. Proses berlanjut ke cakupan luar berikutnya hanya jika tidak ada metode kandidat yang ditemukan. Proses ini lebih dekat mengikuti algoritma umum untuk resolusi kelebihan beban. Jika semua metode kandidat yang ditemukan pada cakupan tertentu tidak cocok, grup metode tidak memiliki jenis alami.

Anda dapat membaca detail perubahan dalam spesifikasi proposal.

Akses indeks implisit

Operator indeks implisit "dari ujung", ^, sekarang diizinkan dalam ekspresi inisialisasi objek untuk koleksi berdimensi tunggal. Misalnya, Anda sekarang dapat menginisialisasi array dimensi tunggal menggunakan penginisialisasi objek seperti yang ditunjukkan dalam kode berikut:

public class TimerRemaining
{
    public int[] buffer { get; set; } = new int[10];
}

var countdown = new TimerRemaining()
{
    buffer =
    {
        [^1] = 0,
        [^2] = 1,
        [^3] = 2,
        [^4] = 3,
        [^5] = 4,
        [^6] = 5,
        [^7] = 6,
        [^8] = 7,
        [^9] = 8,
        [^10] = 9
    }
};

Kelas TimerRemaining mencakup array buffer yang diinisialisasi dengan ukuran panjang 10. Contoh sebelumnya menetapkan nilai ke array ini menggunakan operator indeks "dari akhir" (^), secara efektif membuat array yang menghitung mundur dari 9 hingga 0.

Dalam versi sebelum C# 13, ^ operator tidak dapat digunakan dalam penginisialisasi objek. Anda perlu mengindeks elemen dari depan.

ref dan unsafe dalam iterator dan async fungsi

Fitur ini dan dua fitur berikut memungkinkan tipe-tipe ref struct untuk menggunakan konstruksi baru. Anda tidak akan menggunakan fitur-fitur ini kecuali Anda menulis tipe Anda sendiri ref struct. Kemungkinan besar, Anda melihat manfaat tidak langsung sebagai System.Span<T> dan System.ReadOnlySpan<T> mendapatkan lebih banyak fungsionalitas.

Sebelum C# 13, metode iterator (metode yang menggunakan yield return) dan async metode tidak dapat mendeklarasikan variabel lokal ref , juga tidak dapat memiliki unsafe konteks.

Dalam C# 13, async metode dapat mendeklarasikan ref variabel lokal, atau variabel lokal jenis ref struct . Namun, variabel tersebut tidak dapat diakses melintasi batas await. Mereka juga tidak dapat diakses melintasi batas yield return.

Pembatasan yang dilonggarkan ini memungkinkan pengkompilasi untuk mengizinkan penggunaan variabel lokal ref dan jenis ref struct yang terverifikasi aman di lebih banyak tempat. Anda dapat menggunakan jenis dengan aman seperti System.ReadOnlySpan<T> dalam metode ini. Pengkompilasi memberi tahu Anda jika Anda melanggar aturan keselamatan.

Dalam cara yang sama, C# 13 mengizinkan konteks unsafe di dalam metode iterator. Namun, semua pernyataan yield return dan yield break harus dalam konteks yang aman.

allows ref struct

Sebelum C# 13, ref struct jenis tidak dapat dinyatakan sebagai argumen jenis untuk jenis atau metode generik. Sekarang, deklarasi jenis generik dapat menambahkan anti-batasan, allows ref struct. Pembatasan terbalik ini menyatakan bahwa argumen tipe yang disediakan untuk parameter tipe tersebut dapat berupa ref struct tipe. Kompilator memberlakukan aturan keamanan ref pada semua instans parameter jenis tersebut.

Misalnya, Anda mungkin mendeklarasikan jenis generik seperti kode berikut:

public class C<T> where T : allows ref struct
{
    // Use T as a ref struct:
    public void M(scoped T p)
    {
        // The parameter p must follow ref safety rules
    }
}

Ini memungkinkan jenis seperti System.Span<T> dan System.ReadOnlySpan<T> digunakan dengan algoritma generik, jika berlaku. Anda dapat mempelajari lebih lanjut di artikel pembaruan untuk where dan panduan pemrograman tentang batasan generik.

ref struct Antarmuka

Sebelum C# 13, ref struct jenis tidak diizinkan untuk menerapkan antarmuka. Dimulai dengan C# 13, mereka bisa. Anda dapat menyatakan bahwa ref struct jenis mengimplementasikan antarmuka. Namun, untuk memastikan aturan keamanan referensi, jenis ref struct tidak dapat dikonversi menjadi jenis antarmuka. Konversi itu adalah konversi tinju, dan dapat melanggar keamanan ref. Deklarasi metode antarmuka eksplisit dalam ref struct hanya dapat diakses melalui parameter tipe allows ref struct di mana parameter tipe tersebut . Selain itu, ref struct jenis harus mengimplementasikan semua metode yang dideklarasikan dalam antarmuka, termasuk metode tersebut dengan implementasi default.

Pelajari selengkapnya dalam pembaruan pada ref struct jenis dan penambahan batasan allows ref struct generik.

Lebih banyak anggota parsial

Anda dapat mendeklarasikan partial properti dan partial pengindeks di C# 13. Properti parsial dan pengindeks umumnya mengikuti aturan yang sama dengan metode: Anda membuat satu partial dan satu deklarasi implementasi. Tanda tangan dari dua deklarasi harus cocok. Salah satu batasannya adalah Anda tidak dapat menggunakan deklarasi properti otomatis untuk menerapkan properti parsial. Properti yang tidak mendeklarasikan isi dianggap sebagai deklarasi pendefinisian.

public partial class C
{
    // Declaring declaration
    public partial string Name { get; set; }
}

public partial class C
{
    // implementation declaration:
    private string _name;
    public partial string Name
    {
        get => _name;
        set => _name = value;
    }
}

Anda dapat mempelajari selengkapnya dalam artikel tentang anggota parsial.

Prioritas resolusi kelebihan beban

Di C# 13, pengkompilasi mengenali OverloadResolutionPriorityAttribute untuk memilih satu fungsi overload daripada yang lainnya. Penulis pustaka dapat menggunakan atribut ini untuk memastikan bahwa kelebihan beban baru yang lebih baik lebih disukai daripada kelebihan beban yang ada. Misalnya, Anda mungkin menambahkan kelebihan beban baru yang lebih berkinerja. Anda tidak ingin memutus kode yang sudah ada yang menggunakan pustaka Anda, tetapi Anda ingin pengguna memperbarui ke versi baru saat mereka mengkompilasi ulang. Anda dapat menggunakan prioritas resolusi kelebihan muatan untuk memberi tahu kompilator mengenai overload mana yang harus diutamakan. Kelebihan beban dengan prioritas tertinggi lebih disukai.

Fitur ini ditujukan bagi penulis pustaka untuk menghindari ambiguitas saat menambahkan kelebihan beban baru. Penulis pustaka harus berhati-hati dengan atribut ini untuk menghindari kebingungan.

Kata kunci field

Kata field kunci kontekstual ada di C# 13 sebagai fitur pratinjau. Token field mengakses bidang penyimpanan yang dibuat oleh kompilator di pengakses properti. Ini memungkinkan Anda menulis isi aksesor tanpa mendeklarasikan bidang dukungan eksplisit dalam deklarasi jenis Anda. Anda dapat mendeklarasikan isi untuk satu atau kedua aksesor untuk properti yang didukung oleh variabel.

Fitur field ini dirilis sebagai fitur pratinjau. Kami ingin belajar dari pengalaman Anda menggunakannya. Ada potensi perubahan yang dapat menyebabkan kerusakan atau kebingungan saat membaca kode pada tipe yang juga menyertakan bidang bernama field. Anda dapat menggunakan @field atau this.field untuk membedakan antara field kata kunci dan pengidentifikasi.

Penting

Anda harus berhati-hati menggunakan field fitur kata kunci di kelas yang memiliki bidang bernama field. Kata kunci baru field menutupi kolom bernama field dalam lingkup aksesor properti. Anda dapat mengubah nama field variabel, atau menggunakan @ token untuk mereferensikan field pengidentifikasi sebagai @field. Anda dapat mempelajari lebih lanjut dengan membaca spesifikasi fitur untuk field kata kunci.

Jika Anda mencoba fitur ini dan memiliki umpan balik, masukkan ke dalam isu fitur di repositori csharplang.

Lihat juga