Jenis nilai yang dapat diubah ke null (referensi C#)
Jenis T?
nilai nullable mewakili semua nilai dari jenis T
nilai yang mendasar dan nilai null tambahan. Sebagai contoh, Anda dapat menetapkan salah satu dari tiga nilai berikut ke variabel bool?
: true
, false
, atau null
. Jenis nilai T
yang mendasar tidak boleh berupa tipe nilai nullable itu sendiri.
Jenis nilai yang dapat diubah ke null adalah instans struktur generik System.Nullable<T>. Anda bisa merujuk ke jenis nilai yang dapat diubah ke null dengan jenis T
yang mendasar dalam salah satu bentuk yang dapat dipertukarkan berikut: Nullable<T>
atau T?
.
Anda biasanya menggunakan jenis nilai yang dapat diubah ke null saat Anda perlu mewakili nilai yang tidak ditentukan dari jenis nilai yang mendasar. Misalnya, variabel Boolean, atau bool
, hanya dapat berupa true
atau false
. Namun, dalam beberapa aplikasi nilai variabel dapat tidak terdefinisi atau hilang. Misalnya, basis data mungkin berisi true
atau false
, atau mungkin tidak berisi nilai apa pun, yaitu, NULL
. Anda bisa menggunakan jenis bool?
dalam skenario tersebut.
Deklarasi dan penugasan
Karena jenis nilai secara implisit dapat dikonversi ke jenis nilai yang dapat diubah ke null yang sesuai, Anda dapat menetapkan nilai ke variabel jenis nilai yang dapat diubah ke null seperti yang Akan Anda lakukan untuk jenis nilai yang mendasarinya. Anda juga dapat menetapkan nilai null
. Contohnya:
double? pi = 3.14;
char? letter = 'a';
int m2 = 10;
int? m = m2;
bool? flag = null;
// An array of a nullable value type:
int?[] arr = new int?[10];
Nilai default dari jenis nilai yang dapat diubah ke null mewakili null
, yang adalah instans Nullable<T>.HasValueyang propertinya mengembalikan false
.
Pemeriksaan instans jenis nilai yang dapat diubah ke null
Anda dapat menggunakan is
operator dengan pola jenis untuk memeriksa instans jenis nilai nullable untuk null
dan mengambil nilai dari jenis yang mendasar:
int? a = 42;
if (a is int valueOfA)
{
Console.WriteLine($"a is {valueOfA}");
}
else
{
Console.WriteLine("a does not have a value");
}
// Output:
// a is 42
Anda selalu dapat menggunakan properti baca-saja berikut untuk memeriksa dan mendapatkan nilai variabel jenis nilai yang dapat diubah ke null:
Nullable<T>.HasValue menunjukkan apakah instans jenis nilai yang dapat diubah ke null memiliki nilai dari jenis yang mendasarnya.
Nullable<T>.Value mendapatkan nilai dari jenis yang mendasar jika HasValue adalah
true
. Jika HasValue adalahfalse
, Value properti melempar InvalidOperationException.
Contoh berikut menggunakan properti HasValue
untuk menguji apakah variabel berisi nilai sebelum menampilkannya:
int? b = 10;
if (b.HasValue)
{
Console.WriteLine($"b is {b.Value}");
}
else
{
Console.WriteLine("b does not have a value");
}
// Output:
// b is 10
Anda juga dapat membandingkan variabel jenis nilai yang dapat diubah ke null dengan null
alih-alih menggunakan properti HasValue
, seperti yang ditunjukkan contoh berikut:
int? c = 7;
if (c != null)
{
Console.WriteLine($"c is {c.Value}");
}
else
{
Console.WriteLine("c does not have a value");
}
// Output:
// c is 7
Konversi dari jenis nilai yang dapat diubah ke tipe yang mendasar
Jika Anda ingin menetapkan nilai jenis nilai nullable ke variabel jenis nilai yang tidak dapat diubah ke null, Anda mungkin perlu menentukan nilai yang akan ditetapkan sebagai pengganti null
. Gunakan operator null-coalescing??
untuk melakukannya (Anda juga dapat menggunakan metode Nullable<T>.GetValueOrDefault(T) untuk tujuan yang sama):
int? a = 28;
int b = a ?? -1;
Console.WriteLine($"b is {b}"); // output: b is 28
int? c = null;
int d = c ?? -1;
Console.WriteLine($"d is {d}"); // output: d is -1
Jika Anda ingin menggunakan nilai default dari jenis nilai yang mendasar sebagai ganti null
, gunakan metode Nullable<T>.GetValueOrDefault().
Anda juga dapat secara eksplisit melemparkan tipe nilai yang dapat diubah ke null ke tipe yang tidak dapat dibatalkan, seperti yang ditunjukkan oleh contoh berikut:
int? n = null;
//int m1 = n; // Doesn't compile
int n2 = (int)n; // Compiles, but throws an exception if n is null
Pada durasi, jika nilai jenis nilai yang dapat diubah ke null adalah null
, transmisi eksplisit akan melemparkan InvalidOperationException.
Jenis nilai T
yang tidak dapat diubah ke null secara implisit dapat dikonversi ke jenis nilai yang dapat diubah ke null T?
yang sesuai.
Operator yang terangkat
Operator unary dan biner yang telah ditentukan sebelumnya atau operator yang kelebihan beban yang didukung oleh jenis T
nilai juga didukung oleh jenis T?
nilai yang dapat diubah ke null yang sesuai. Operator ini, juga dikenal sebagai operator yang diangkat, menghasilkan null
jika satu atau kedua operan ; null
jika tidak, operator menggunakan nilai yang terkandung dari operannya untuk menghitung hasilnya. Contoh:
int? a = 10;
int? b = null;
int? c = 10;
a++; // a is 11
a = a * c; // a is 110
a = a + b; // a is null
Catatan
Untuk jenisnyabool?
, operator dan &
yang telah ditentukan |
sebelumnya tidak mengikuti aturan yang dijelaskan di bagian ini: hasil evaluasi operator bisa non-null meskipun salah satu operan adalah null
. Untuk informasi selengkapnya, lihat bagian Operator logis Boolean yang dapat diubah ke null dari artikel Operator logis Boolean .
Untuk operator <
perbandingan , , >
, <=
dan >=
, jika satu atau kedua operand adalah null
, hasilnya adalah false
; jika tidak, nilai operand yang terkandung dibandingkan. Jangan berasumsi bahwa karena perbandingan tertentu (misalnya, <=
) mengembalikan false
, perbandingan yang berlawanan (>
) mengembalikan true
. Contoh berikut ini menunjukkan bahwa 10 adalah
- Lebih dari atau sama dengan
null
- kurang dari
null
int? a = 10;
Console.WriteLine($"{a} >= null is {a >= null}");
Console.WriteLine($"{a} < null is {a < null}");
Console.WriteLine($"{a} == null is {a == null}");
// Output:
// 10 >= null is False
// 10 < null is False
// 10 == null is False
int? b = null;
int? c = null;
Console.WriteLine($"null >= null is {b >= c}");
Console.WriteLine($"null == null is {b == c}");
// Output:
// null >= null is False
// null == null is True
Untuk operator ==
kesetaraan , jika kedua operand adalah null
, hasilnya adalah true
, jika hanya salah satu operand adalah , hasilnya adalah null
false
; jika tidak, nilai operand yang terkandung dibandingkan.
Untuk operator !=
ketidaksetaraan , jika kedua operand adalah null
, hasilnya adalah false
, jika hanya salah satu operand adalah , hasilnya adalah null
true
; jika tidak, nilai operand yang terkandung dibandingkan.
Jika ada konversi yang ditentukan pengguna antara dua jenis nilai, konversi yang sama juga dapat digunakan di antara jenis nilai nullable yang sesuai.
Boxing dan Unboxing
Instans jenis T?
nilai yang dapat diubah ke null dikotak sebagai berikut:
- Jika HasValue mengembalikan
false
, referensi null diproduksi. - Jika HasValue mengembalikan
true
, nilai terkait dari jenis nilai yang mendasarT
dikotak, bukan instans Nullable<T>.
Anda bisa membuka kotak nilai berjenis nilai T
ke jenis nilai nullable terkait T?
, seperti yang ditunjukkan contoh berikut:
int a = 41;
object aBoxed = a;
int? aNullable = (int?)aBoxed;
Console.WriteLine($"Value of aNullable: {aNullable}");
object aNullableBoxed = aNullable;
if (aNullableBoxed is int valueOfA)
{
Console.WriteLine($"aNullableBoxed is boxed int: {valueOfA}");
}
// Output:
// Value of aNullable: 41
// aNullableBoxed is boxed int: 41
Cara mengidentifikasi jenis nilai yang dapat diubah ke null
Contoh berikut menunjukkan cara menentukan apakah System.Type instans mewakili jenis nilai nullable yang dibangun, yaitu jenis System.Nullable<T> dengan parameter T
jenis tertentu :
Console.WriteLine($"int? is {(IsNullable(typeof(int?)) ? "nullable" : "non nullable")} value type");
Console.WriteLine($"int is {(IsNullable(typeof(int)) ? "nullable" : "non-nullable")} value type");
bool IsNullable(Type type) => Nullable.GetUnderlyingType(type) != null;
// Output:
// int? is nullable value type
// int is non-nullable value type
Seperti yang ditunjukkan contoh, Anda menggunakan operator typeof untuk membuat System.Type instans.
Jika Anda ingin menentukan apakah instans memiliki jenis nilai yang dapat diubah ke null, jangan gunakan Object.GetType metode untuk mendapatkan instans yang Type akan diuji dengan kode sebelumnya. Saat Anda memanggil Object.GetType metode pada instans jenis nilai nullable, instans dikotak ke Object. Karena tinju instans non-null dari jenis nilai nullable setara dengan tinju dari nilai dari jenis yang mendasar, GetType mengembalikan instans Type yang mewakili jenis yang mendasar dari jenis nilai yang dapat diubah ke null:
int? a = 17;
Type typeOfA = a.GetType();
Console.WriteLine(typeOfA.FullName);
// Output:
// System.Int32
Selain itu, jangan gunakan operator is untuk menentukan apakah instans adalah jenis nilai yang dapat diubah ke null. Seperti yang ditunjukkan contoh berikut, Anda tidak dapat membedakan jenis instans jenis nilai yang dapat diubah ke null dan instans jenis yang mendasarnya dengan is
operator:
int? a = 14;
if (a is int)
{
Console.WriteLine("int? instance is compatible with int");
}
int b = 17;
if (b is int?)
{
Console.WriteLine("int instance is compatible with int?");
}
// Output:
// int? instance is compatible with int
// int instance is compatible with int?
Sebagai gantinya Nullable.GetUnderlyingType gunakan dari contoh pertama dan operator typeof untuk memeriksa apakah instans memiliki jenis nilai yang dapat diubah ke null.
Catatan
Metode yang dijelaskan di bagian ini tidak berlaku dalam kasus jenis referensi yang dapat diubah ke null.
Spesifikasi bahasa C#
Untuk informasi selengkapnya, lihat bagian berikut dari spesifikasi bahasa C#:
- Jenis yang dapat diubah ke null
- Operator yang terangkat
- Konversi implisit yang dapat diubah ke null
- Konversi yang dapat diubah ke null eksplisit
- Operator yang terangkat