Bagikan melalui


Apa yang baru di C# 14

C# 14 menyertakan fitur baru berikut. Anda dapat mencoba fitur-fitur ini menggunakan versi Visual Studio 2026 terbaru atau .NET 10 SDK:

C# 14 adalah rilis C# terbaru. C# 14 didukung pada .NET 10. Untuk informasi selengkapnya, lihat Penerapan versi bahasa C#.

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

Anda dapat menemukan perubahan yang mengganggu yang diperkenalkan di C# 14 di artikel kami tentang perubahan yang mengganggu.

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 .

Anggota ekstensi

C# 14 menambahkan sintaks baru untuk menentukan anggota ekstensi. Sintaks baru memungkinkan Anda mendeklarasikan properti ekstensi selain metode ekstensi. Anda juga dapat mendeklarasikan anggota ekstensi yang memperluas tipe, bukan instans dari tipe tersebut. Dengan kata lain, anggota ekstensi baru ini dapat muncul sebagai anggota statis dari jenis yang Anda perluas. Ekstensi ini dapat mencakup operator yang ditentukan pengguna yang diimplementasikan sebagai metode ekstensi statis. Contoh kode berikut menunjukkan contoh berbagai jenis anggota ekstensi yang dapat Anda nyatakan:

public static class Enumerable
{
    // Extension block
    extension<TSource>(IEnumerable<TSource> source) // extension members for IEnumerable<TSource>
    {
        // Extension property:
        public bool IsEmpty => !source.Any();

        // Extension method:
        public IEnumerable<TSource> Where(Func<TSource, bool> predicate) { ... }
    }

    // extension block, with a receiver type only
    extension<TSource>(IEnumerable<TSource>) // static extension members for IEnumerable<Source>
    {
        // static extension method:
        public static IEnumerable<TSource> Combine(IEnumerable<TSource> first, IEnumerable<TSource> second) { ... }

        // static extension property:
        public static IEnumerable<TSource> Identity => Enumerable.Empty<TSource>();

        // static user defined operator:
        public static IEnumerable<TSource> operator + (IEnumerable<TSource> left, IEnumerable<TSource> right) => left.Concat(right);
    }
}

Anggota di blok ekstensi pertama dipanggil seolah-olah mereka adalah anggota instans , IEnumerable<TSource>misalnya sequence.IsEmpty. Anggota di blok ekstensi kedua dipanggil seolah-olah mereka adalah anggota statis , IEnumerable<TSource>misalnya IEnumerable<int>.Identity.

Anda dapat mempelajari detail selengkapnya dengan membaca artikel tentang anggota ekstensi di panduan pemrograman, artikel referensi bahasa pada extension kata kunci, dan spesifikasi fitur untuk fitur anggota ekstensi baru.

Kata kunci field

Token field memungkinkan Anda menulis isi aksesor properti tanpa mendeklarasikan bidang dukungan eksplisit. Token field diganti dengan bidang backing yang disintesis kompilator.

Misalnya, sebelumnya, jika Anda ingin memastikan bahwa properti string tidak dapat disetel ke null, Anda harus mendeklarasikan variabel penampung dan mengimplementasikan kedua metode akses.

private string _msg;
public string Message
{
    get => _msg;
    set => _msg = value ?? throw new ArgumentNullException(nameof(value));
}

Anda sekarang dapat menyederhanakan kode Anda untuk:

public string Message
{
    get;
    set => field = value ?? throw new ArgumentNullException(nameof(value));
}

Anda dapat mendeklarasikan isi untuk satu atau kedua aksesor untuk properti yang didukung oleh variabel.

Ada potensi perubahan yang berpotensi merusak atau kebingungan membaca kode dalam tipe yang juga menyertakan simbol bernama field. Anda dapat menggunakan @field atau this.field untuk membedakan antara field kata kunci dan pengidentifikasi, atau Anda dapat mengganti nama simbol saat ini field untuk memberikan perbedaan yang lebih baik.

Konversi rentang implisit

C# 14 memperkenalkan dukungan kelas satu untuk System.Span<T> dan System.ReadOnlySpan<T> dalam bahasa. Dukungan ini melibatkan konversi implisit baru yang memungkinkan pemrograman yang lebih alami dengan jenis ini.

Span<T> dan ReadOnlySpan<T> digunakan dalam banyak cara utama dalam C# dan runtime. Perkenalan mereka meningkatkan performa tanpa mempertaruhkan keselamatan. C# 14 mengenali hubungan dan mendukung beberapa konversi antara ReadOnlySpan<T>, , Span<T>dan T[]. Tipe rentang dapat berupa penerima metode ekstensi, menggabungkan dengan konversi lain, dan membantu skenario inferensi jenis generik.

Anda dapat menemukan daftar konversi rentang implisit dalam artikel tentang jenis bawaan di bagian referensi bahasa. Anda dapat mempelajari detail selengkapnya dengan membaca spesifikasi fitur untuk Jenis rentang kelas satu.

Jenis generik yang tidak terikat dan nameof

Dimulai dengan C# 14, argumen untuk nameof bisa menjadi jenis generik yang tidak terikat. Misalnya, nameof(List<>) dievaluasi ke List. Dalam versi C#sebelumnya, hanya jenis generik tertutup, seperti List<int>, yang dapat digunakan untuk mengembalikan List nama.

Parameter lambda sederhana dengan pengubah

Anda dapat menambahkan pengubah parameter, seperti scoped, , refin, out, atau ref readonly ke parameter ekspresi lambda tanpa menentukan jenis parameter:

delegate bool TryParse<T>(string text, out T result);
// ...
TryParse<int> parse1 = (text, out result) => Int32.TryParse(text, out result);

Sebelumnya, menambahkan pengubah apa pun hanya diizinkan ketika deklarasi parameter menyertakan jenis untuk parameter. Deklarasi sebelumnya akan memerlukan jenis pada semua parameter:

TryParse<int> parse2 = (string text, out int result) => Int32.TryParse(text, out result);

Pengubah params masih memerlukan daftar parameter yang ditik secara eksplisit.

Anda dapat membaca selengkapnya tentang perubahan ini dalam artikel tentang ekspresi lambda dalam referensi bahasa C#.

Lebih banyak anggota parsial

Anda sekarang dapat mendeklarasikan konstruktor instans dan peristiwa sebagai anggota parsial.

Konstruktor parsial dan peristiwa parsial harus mencakup persis satu deklarasi yang mendefinisikan dan satu deklarasi penerapan.

Hanya deklarasi penerapan konstruktor parsial yang dapat menyertakan inisialisasi konstruktor: this() atau base(). Hanya satu deklarasi jenis parsial yang dapat menyertakan sintaks konstruktor utama.

Deklarasi penerapan peristiwa parsial harus mencakup pengakses add dan remove. Deklarasi yang menentukan mendefinisikan suatu event mirip field.

Penugasan gabungan yang dikustomisasi pengguna

Anda dapat mempelajari lebih lanjut dalam spesifikasi fitur untuk penetapan majemuk yang ditentukan pengguna.

Penetapan dengan kondisi null

Operator akses anggota bersyarat-null, ?. dan ?[], sekarang dapat digunakan di sisi kiri penugasan atau penugasan gabungan.

Sebelum C# 14, Anda perlu memeriksa variabel null sebelum menetapkan ke properti:

if (customer is not null)
{
    customer.Order = GetCurrentOrder();
}

Anda dapat menyederhanakan kode sebelumnya menggunakan ?. operator:

customer?.Order = GetCurrentOrder();

Sisi kanan = operator dievaluasi hanya ketika sisi kiri tidak null. Jika customer null, kode tidak memanggil GetCurrentOrder.

Selain pengoperasian penugasan, Anda dapat menggunakan operator akses anggota null-conditional dengan operator penugasan gabungan (+=, -=, dan lainnya). Namun, kenaikan dan penurunan, ++ dan --, tidak diizinkan.

Anda dapat mempelajari lebih lanjut di artikel referensi bahasa tentang akses anggota bersyarat dan spesifikasi fitur untuk penetapan bersyarat null.

Lihat juga