Bagikan melalui


Jenis referensi yang dapat diubah ke null (referensi C#)

Catatan

Artikel ini mencakup jenis referensi yang dapat diubah ke null. Anda juga dapat mendeklarasikan jenis nilai yang dapat diubah ke null.

Anda dapat menggunakan jenis referensi nullable dalam kode yang berada dalam konteks sadar null. Jenis referensi yang dapat diubah ke null, peringatan analisis statik null, dan operator null-forgiving adalah fitur bahasa opsional. Semua dinonaktifkan secara default. Anda mengontrol konteks nullable di tingkat proyek dengan menggunakan pengaturan build, atau dalam kode dengan menggunakan pragma.

Referensi bahasa C# mendanai versi bahasa C# yang terbaru dirilis. Ini juga berisi dokumentasi awal untuk fitur dalam pratinjau publik untuk rilis bahasa yang akan datang.

Dokumentasi mengidentifikasi fitur apa pun yang pertama kali diperkenalkan dalam tiga versi terakhir bahasa atau dalam pratinjau publik saat ini.

Tip

Untuk menemukan kapan fitur pertama kali diperkenalkan di C#, lihat artikel tentang riwayat versi bahasa C#.

Penting

Semua templat proyek memungkinkan konteks nullable untuk proyek. Proyek yang dibuat dengan template sebelumnya tidak menyertakan elemen ini, dan fitur ini tidak aktif kecuali Anda mengaktifkannya di file proyek atau menggunakan pragma.

Dalam konteks sadar yang dapat diubah ke null:

  • Anda harus menginisialisasi variabel jenis T referensi dengan nilai non-null, dan Anda tidak pernah dapat menetapkan nilai yang mungkin null.
  • Anda dapat menginisialisasi variabel jenis T? referensi dengan null atau menetapkan null, tetapi Anda harus memeriksanya null sebelum dereferensi.
  • Ketika Anda menerapkan operator pengampunan null ke variabel m jenis T?, seperti dalam m!, variabel dianggap non-null.

Kompilator memberlakukan perbedaan antara jenis T referensi yang tidak dapat diubah ke null dan jenis T? referensi null dengan menggunakan aturan sebelumnya. Variabel jenis T dan variabel jenis T? adalah jenis .NET yang sama. Contoh berikut mendeklarasikan string yang tidak dapat diubah ke null dan string yang dapat diubah ke null, lalu menggunakan operator null-forgiving untuk menetapkan nilai ke string yang tidak dapat diubah ke null:

string notNull = "Hello";
string? nullable = default;
notNull = nullable!; // null forgiveness

Variabel notNull dan nullable keduanya menggunakan jenis .String Karena jenis yang tidak dapat diubah ke null dan dapat diubah ke null keduanya menggunakan jenis yang sama, Anda tidak dapat menggunakan jenis referensi yang dapat diubah ke null di beberapa lokasi. Secara umum, Anda tidak dapat menggunakan jenis referensi nullable sebagai kelas dasar atau antarmuka yang diimplementasikan. Anda tidak dapat menggunakan jenis referensi nullable dalam pembuatan objek atau ekspresi pengujian jenis apa pun. Anda tidak dapat menggunakan tipe referensi yang dapat diubah ke null sebagai jenis ekspresi akses anggota. Contoh berikut menunjukkan konstruksi ini:

public MyClass : System.Object? // not allowed
{
}

var nullEmpty = System.String?.Empty; // Not allowed
var maybeObject = new object?(); // Not allowed
try
{
    if (thing is string? nullableString) // not allowed
        Console.WriteLine(nullableString);
} catch (Exception? e) // Not Allowed
{
    Console.WriteLine("error");
}

Referensi yang dapat diubah ke null dan analisis statik

Contoh di bagian sebelumnya mengilustrasikan sifat jenis referensi yang dapat diubah ke null. Jenis referensi yang dapat diubah ke null bukanlah jenis kelas baru, melainkan anotasi pada jenis referensi yang ada. Kompilator menggunakan anotasi tersebut untuk membantu Anda menemukan potensi kesalahan referensi null dalam kode Anda. Tidak ada perbedaan runtime antara jenis referensi yang tidak dapat diubah ke null dan jenis referensi yang dapat diubah ke null. Kompilator tidak menambahkan pemeriksaan runtime untuk jenis referensi yang tidak dapat diubah ke null. Keuntungannya ada pada analisis waktu kompilasi. Kompilator menghasilkan peringatan yang membantu Anda menemukan dan memperbaiki potensi kesalahan null dalam kode Anda. Anda mendeklarasikan niat Anda, dan kompilator memperingatkan Anda ketika kode Anda melanggar niat tersebut.

Penting

Anotasi referensi yang dapat diubah tidak memperkenalkan perubahan perilaku, tetapi pustaka lain mungkin menggunakan pantulan untuk menghasilkan perilaku runtime yang berbeda untuk jenis referensi nullable dan tidak dapat diubah ke null. Yang perlu diperhatikan, Entity Framework Core membaca atribut nullable. Ini menafsirkan referensi nullable sebagai nilai opsional, dan referensi non-nullable sebagai nilai yang diperlukan.

Dalam konteks yang diaktifkan yang dapat diubah ke null, kompilator melakukan analisis statik pada variabel dari semua jenis referensi, baik yang dapat diubah ke null dan yang tidak dapat diubah ke null. Kompilator melacak status null dari setiap variabel referensi sebagai bukan null atau mungkin null. Status default referensi yang tidak dapat diubah ke null adalah bukan null. Status default referensi yang dapat diubah ke null adalah mungkin null.

Jenis referensi yang tidak dapat diubah ke null harus selalu aman untuk direferensikan karena status null-nya adalah bukan null. Untuk memberlakukan aturan tersebut, kompilator mengeluarkan peringatan jika jenis referensi yang tidak dapat diubah ke null tidak diinisialisasi ke nilai yang bukan null. Anda harus menetapkan variabel lokal tempat Anda mendeklarasikannya. Setiap bidang harus diberi nilai bukan null, dalam penginisialisasi bidang atau setiap konstruktor. Kompilator mengeluarkan peringatan saat referensi yang tidak dapat diubah ke null ditetapkan ke referensi yang statusnya mungkin null. Umumnya, referensi yang tidak dapat diubah ke null bukan nol dan tidak ada peringatan yang dikeluarkan saat Anda mendereferensikan variabel tersebut.

Catatan

Jika Anda menetapkan ekspresi mungkin-null ke jenis referensi yang tidak dapat diubah ke null, pengkompilasi akan menghasilkan peringatan. Kompilator kemudian membuat peringatan untuk variabel tersebut hingga variabel tersebut ditetapkan ke ekspresi bukan null.

Anda dapat menginisialisasi atau menetapkan null ke jenis referensi nullable. Oleh karena itu, analisis statik harus menentukan bahwa suatu variabel bukan null sebelum direferensikan. Jika referensi nullable ditentukan mungkin-null, menetapkannya ke variabel referensi yang tidak dapat diubah ke null menghasilkan peringatan kompilator. Kelas berikut menunjukkan contoh peringatan ini:

public class ProductDescription
{
    private string shortDescription;
    private string? detailedDescription;

    public ProductDescription() // Warning! shortDescription not initialized.
    {
    }

    public ProductDescription(string productDescription) =>
        this.shortDescription = productDescription;

    public void SetDescriptions(string productDescription, string? details=null)
    {
        shortDescription = productDescription;
        detailedDescription = details;
    }

    public string GetDescription()
    {
        if (detailedDescription.Length == 0) // Warning! dereference possible null
        {
            return shortDescription;
        }
        else
        {
            return $"{shortDescription}\n{detailedDescription}";
        }
    }

    public string FullDescription()
    {
        if (detailedDescription == null)
        {
            return shortDescription;
        }
        else if (detailedDescription.Length > 0) // OK, detailedDescription can't be null.
        {
            return $"{shortDescription}\n{detailedDescription}";
        }
        return shortDescription;
    }
}

Cuplikan berikut menunjukkan di mana compiler mengeluarkan peringatan saat menggunakan kelas ini:

string shortDescription = default; // Warning! non-nullable set to null;
var product = new ProductDescription(shortDescription); // Warning! static analysis knows shortDescription maybe null.

string description = "widget";
var item = new ProductDescription(description);

item.SetDescriptions(description, "These widgets will do everything.");

Contoh sebelumnya menunjukkan bagaimana analisis statik kompilator menentukan status null dari variabel referensi. Kompilator menerapkan aturan bahasa untuk pemeriksaan dan penugasan null untuk menginformasikan analisisnya. Kompilator tidak dapat membuat asumsi tentang semantik metode atau properti. Jika Anda memanggil metode yang melakukan pemeriksaan null, kompilator tidak dapat mengetahui bahwa metode tersebut memengaruhi status null variabel. Anda dapat menambahkan atribut ke API Anda untuk menginformasikan pengkompilasi tentang semantik argumen dan mengembalikan nilai. Banyak API umum di pustaka .NET memiliki atribut ini. Misalnya, pengkompilasi menafsirkan IsNullOrEmpty dengan benar sebagai pemeriksaan null. Untuk informasi selengkapnya tentang atribut yang berlaku untuk analisis statik status null, lihat artikel tentang Atribut yang dapat diubah ke null.

Mengatur konteks yang dapat diubah ke null

Anda dapat mengontrol konteks nullable dengan dua cara. Di tingkat proyek, tambahkan <Nullable>enable</Nullable> pengaturan proyek. Dalam satu file sumber C#, tambahkan #nullable enable pragma untuk mengaktifkan konteks nullable. Lihat artikel tentang menetapkan strategi yang dapat diubah ke null. Sebelum .NET 6, proyek baru menggunakan default, <Nullable>disable</Nullable>. Dimulai dengan .NET 6, proyek baru menyertakan elemen <Nullable>enable</Nullable> dalam file proyek.

Spesifikasi bahasa C#

Untuk informasi selengkapnya, lihat bagian Jenis referensi nullable dari spesifikasi bahasa C#.

Lihat juga