Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Nota
Artikel ini adalah spesifikasi fitur. Spesifikasi berfungsi sebagai dokumen desain untuk fitur tersebut. Ini termasuk perubahan spesifikasi yang diusulkan, bersama dengan informasi yang diperlukan selama desain dan pengembangan fitur. Artikel ini diterbitkan sampai perubahan spesifikasi yang diusulkan diselesaikan dan dimasukkan dalam spesifikasi ECMA saat ini.
Mungkin ada beberapa perbedaan antara spesifikasi fitur dan implementasi yang selesai. Perbedaan tersebut dicatat dalam catatan penting rapat desain bahasa (LDM) .
Anda dapat mempelajari lebih lanjut tentang proses untuk mengadopsi speklet fitur ke dalam standar bahasa C# dalam artikel tentang spesifikasi .
Edisi juara: https://github.com/dotnet/csharplang/issues/3297
Ringkasan
Izinkan anotasi nullable untuk parameter jenis yang tidak dibatasi oleh jenis nilai atau jenis referensi: T?
.
static T? FirstOrDefault<T>(this IEnumerable<T> collection) { ... }
anotasi ?
Di C#8, anotasi ?
hanya dapat diterapkan ke parameter jenis yang secara eksplisit dibatasi untuk jenis nilai atau jenis referensi.
Di C#9, anotasi ?
dapat diterapkan ke parameter jenis apa pun, terlepas dari batasan.
Kecuali parameter jenis secara eksplisit dibatasi untuk jenis nilai, anotasi hanya dapat diterapkan dalam konteks #nullable enable
.
Jika parameter jenis T
diganti dengan jenis referensi, maka T?
mewakili instans nullable dari jenis referensi tersebut.
var s1 = new string[0].FirstOrDefault(); // string? s1
var s2 = new string?[0].FirstOrDefault(); // string? s2
Jika T
diganti dengan jenis nilai, maka T?
mewakili instans T
.
var i1 = new int[0].FirstOrDefault(); // int i1
var i2 = new int?[0].FirstOrDefault(); // int? i2
Jika T
diganti dengan jenis anotasi U?
, maka T?
mewakili jenis anotasi U?
daripada U??
.
var u1 = new U[0].FirstOrDefault(); // U? u1
var u2 = new U?[0].FirstOrDefault(); // U? u2
Jika T
diganti dengan jenis U
, maka T?
mewakili U?
, bahkan dalam konteks #nullable disable
.
#nullable disable
var u3 = new U[0].FirstOrDefault(); // U? u3
Untuk nilai pengembalian, T?
setara dengan [MaybeNull]T
; untuk nilai argumen, T?
setara dengan [AllowNull]T
.
Kesetaraan penting saat mengambil alih atau menerapkan antarmuka dari rakitan yang dikompilasi dengan C#8.
public abstract class A
{
[return: MaybeNull] public abstract T F1<T>();
public abstract void F2<T>([AllowNull] T t);
}
public class B : A
{
public override T? F1<T>() where T : default { ... } // matches A.F1<T>()
public override void F2<T>(T? t) where T : default { ... } // matches A.F2<T>()
}
batasan default
Untuk kompatibilitas dengan kode yang ada, di mana metode generik yang ditimpa dan diimplementasikan secara eksplisit tidak dapat mencakup klausul batasan eksplisit, T?
dalam metode yang ditimpa atau diimplementasikan secara eksplisit diperlakukan sebagai Nullable<T>
di mana T
adalah tipe nilai.
Untuk mengizinkan anotasi untuk parameter tipe yang dibatasi pada tipe referensi, C#8 mengizinkan kendala eksplisit where T : class
dan where T : struct
pada metode yang ditindih atau diimplementasi secara eksplisit.
class A1
{
public virtual void F1<T>(T? t) where T : struct { }
public virtual void F1<T>(T? t) where T : class { }
}
class B1 : A1
{
public override void F1<T>(T? t) /*where T : struct*/ { }
public override void F1<T>(T? t) where T : class { }
}
Untuk mengizinkan anotasi untuk parameter jenis yang tidak dibatasi untuk jenis referensi atau jenis nilai, C#9 memungkinkan batasan where T : default
baru.
class A2
{
public virtual void F2<T>(T? t) where T : struct { }
public virtual void F2<T>(T? t) { }
}
class B2 : A2
{
public override void F2<T>(T? t) /*where T : struct*/ { }
public override void F2<T>(T? t) where T : default { }
}
Penggunaan pembatasan default
selain pada penggantian metode atau implementasi eksplisit adalah suatu kesalahan.
Ini adalah kesalahan untuk menggunakan batasan default
ketika parameter jenis yang sesuai dalam metode yang ditimpa atau metode antarmuka dibatasi ke jenis referensi atau jenis nilai.
Rapat Desain
C# feature specifications