ref
jenis struktur (referensi C#)
Anda dapat menggunakan pengubah ref
dalam deklarasi jenis struktur. Instans jenis ref struct
dialokasikan pada tumpukan dan tidak dapat lolos ke tumpukan terkelola. Untuk memastikan bahwa, pengkompilasi membatasi penggunaan jenis ref struct
sebagai berikut:
ref struct
Tidak boleh menjadi jenis elemen array.ref struct
Tidak dapat berupa jenis bidang kelas atau non-yangref struct
dideklarasikan.ref struct
Tidak dapat dikotak ke System.ValueType atau System.Object.- Variabel
ref struct
tidak dapat diambil dalam ekspresi lambda atau fungsi lokal. - Sebelum C# 13,
ref struct
variabel tidak dapat digunakan dalamasync
metode . Dimulai dengan C# 13,ref struct
variabel tidak dapat digunakan dalam blokawait
yang sama dengan ekspresi dalamasync
metode . Namun, Anda dapat menggunakanref struct
variabel dalam metode sinkron, misalnya, dalam metode yang mengembalikan Task atau Task<TResult>. - Sebelum C# 13,
ref struct
variabel tidak dapat digunakan dalam iterator. Dimulai dengan C# 13,ref struct
jenis danref
lokal dapat digunakan dalam iterator, asalkan mereka tidak berada dalam segmen kode denganyield return
pernyataan. - Sebelum C# 13,
ref struct
antarmuka tidak dapat diterapkan. Dimulai dengan C# 13,ref
struct dapat menerapkan antarmuka, tetapi harus mematuhi aturan keamanan ref. Misalnya,ref struct
jenis tidak dapat dikonversi ke jenis antarmuka karena memerlukan konversi tinju. - Sebelum C# 13,
ref struct
tidak boleh berupa argumen jenis. Dimulai dengan C# 13,ref struct
dapat berupa argumen jenis ketika parameter jenis menentukan dalam klausanyaallows ref struct
where
.
Biasanya, Anda menentukan ref struct
jenis saat Anda memerlukan jenis yang juga menyertakan anggota data dari jenis ref struct
:
public ref struct CustomRef
{
public bool IsValid;
public Span<int> Inputs;
public Span<int> Outputs;
}
Untuk mendeklarasikan ref struct
sebagai readonly
, gabungkan readonly
pengubah dan ref
dalam deklarasi jenis ( readonly
pengubah harus datang sebelum pengubah ref
):
public readonly ref struct ConversionRequest
{
public ConversionRequest(double rate, ReadOnlySpan<double> values)
{
Rate = rate;
Values = values;
}
public double Rate { get; }
public ReadOnlySpan<double> Values { get; }
}
Di .NET, contoh ref struct
adalah System.Span<T> dan System.ReadOnlySpan<T>.
ref
Bidang
Dimulai dengan C# 11, Anda dapat mendeklarasikan ref
bidang dalam , seperti yang ditunjukkan ref struct
contoh berikut:
public ref struct RefFieldExample
{
private ref int number;
public int GetNumber()
{
if (System.Runtime.CompilerServices.Unsafe.IsNullRef(ref number))
{
throw new InvalidOperationException("The number ref field is not initialized.");
}
return number;
}
}
Bidang ref
dapat memiliki nilai .null
Unsafe.IsNullRef<T>(T) Gunakan metode untuk menentukan apakah ref
bidang adalah null
.
Anda bisa menerapkan pengubah readonly
ke ref
bidang dengan cara berikut:
readonly ref
: Anda dapat menetapkan ulang bidang tersebut= ref
dengan operator hanya di dalam konstruktor atauinit
aksesor. Anda dapat menetapkan nilai dengan=
operator kapan saja yang diizinkan oleh pengubah akses bidang.ref readonly
: Pada titik mana pun, Anda tidak dapat menetapkan nilai dengan operator ke bidang seperti itu=
. Namun, Anda dapat menetapkan ulang bidang dengan= ref
operator.readonly ref readonly
: Anda hanya dapat menetapkan ulang bidang tersebut di konstruktor atauinit
aksesor. Pada titik mana pun, Anda tidak dapat menetapkan nilai ke bidang .
Pengkompilasi memastikan bahwa referensi yang disimpan di ref
bidang tidak melampaui referensinya.
Fitur ref
bidang memungkinkan implementasi jenis yang aman seperti System.Span<T>:
public readonly ref struct Span<T>
{
internal readonly ref T _reference;
private readonly int _length;
// Omitted for brevity...
}
Jenis menyimpan Span<T>
referensi di mana ia mengakses elemen yang bersebelahan dalam memori. Penggunaan referensi memungkinkan instans Span<T>
untuk menghindari penyalinan penyimpanan yang dirujuknya.
Pola sekali pakai
Anda dapat menentukan sekali pakai ref struct
. Untuk melakukan itu, pastikan bahwa ref struct
sesuai dengan pola sekali pakai. Artinya, ia memiliki metode instans Dispose
, yang dapat diakses, tanpa parameter dan memiliki void
jenis pengembalian. Anda dapat menggunakan pernyataan penggunaan atau deklarasi dengan instans sekali pakai ref struct
.
Dimulai dengan C# 13, Anda juga dapat menerapkan IDisposable jenisnya ref struct
. Namun, resolusi kelebihan beban lebih memilih pola sekali pakai ke metode antarmuka. Pengkompilasi menyelesaikan ke IDisposable.Dispose
metode hanya dengan metode yang sesuai Dispose
tidak ditemukan.
Pembatasan untuk ref struct
jenis yang mengimplementasikan antarmuka
Pembatasan ini memastikan bahwa ref struct
jenis yang menerapkan antarmuka mematuhi aturan keamanan ref yang diperlukan.
ref struct
Tidak dapat dikonversi ke instans antarmuka yang diimplementasikannya. Pembatasan ini mencakup konversi implisit saat Anda menggunakanref struct
jenis sebagai argumen saat parameter adalah jenis antarmuka. Konversi menghasilkan konversi tinju, yang melanggar keamanan ref.ref struct
Yang mengimplementasikan antarmuka harus mengimplementasikan semua anggota antarmuka. harusref struct
mengimplementasikan anggota di mana antarmuka menyertakan implementasi default.
Kompilator memberlakukan pembatasan ini. Jika Anda menulis ref struct
jenis yang menerapkan antarmuka, setiap pembaruan baru mungkin menyertakan anggota antarmuka default baru. Hingga Anda memberikan implementasi untuk metode baru ini, aplikasi Anda tidak akan dikompilasi.
Penting
ref struct
Yang mengimplementasikan antarmuka mencakup potensi perubahan pemecahan sumber dan pemecahan biner nanti. Jeda terjadi jika ref struct
mengimplementasikan antarmuka yang ditentukan dalam rakitan lain, dan perakitan tersebut menyediakan pembaruan yang menambahkan anggota default ke antarmuka tersebut.
Pemisah sumber terjadi ketika Anda mengkompilasi ref struct
ulang : Ini harus mengimplementasikan anggota baru, meskipun ada implementasi default.
Pemisah biner terjadi jika Anda meningkatkan rakitan eksternal tanpa mengkompilasi ref struct
ulang jenis dan kode yang diperbarui memanggil implementasi default metode baru. Runtime melemparkan pengecualian saat anggota default diakses.
Spesifikasi bahasa C#
Untuk informasi selengkapnya, lihat bagian berikut dari spesifikasi bahasa C#:
Untuk informasi selengkapnya tentang ref
bidang, lihat catatan proposal peningkatan struct tingkat rendah.