Dalam C #, using
pernyataan digunakan untuk membuang sumber daya secara deterministik tanpa menunggu pemulung. Misalnya, ini dapat digunakan untuk:
Buang perintah atau koneksi SQL,
Tutup aliran, membebaskan sumber yang mendasarinya seperti file,
Elemen GDI + gratis,
dll.
Saya perhatikan bahwa using
semakin sering digunakan dalam kasus-kasus di mana tidak ada yang dibuang, tetapi di mana lebih mudah bagi penelepon untuk menulis using
blok daripada dua perintah terpisah.
Contoh:
MiniProfiler , ditulis oleh tim Stack Overflow, digunakan
using
untuk menunjukkan blok ke profil:using (profiler.Step("Name goes here")) { this.DoSomethingUseful(i - 1); }
Satu pendekatan alternatif adalah memiliki dua blok:
var p = profiler.Start("Name goes here"); this.DoSomethingUseful(i - 1); profiler.Stop(p);
Pendekatan lain adalah menggunakan tindakan:
profiler.Step("Name goes here", () => this.DoSomethingUseful(i - 1));
ASP.NET MVC juga memilih
using
formulir:<% using (Html.BeginForm()) { %> <label for="firstName">Name:</label> <%= Html.TextBox("name")%> <input type="submit" value="Save" /> <% } %>
Apakah penggunaan seperti itu tepat? Cara membenarkannya, mengingat bahwa ada beberapa kelemahan:
Pemula akan hilang, karena penggunaan tersebut tidak sesuai dengan yang dijelaskan dalam buku dan spesifikasi bahasa,
Kode harus ekspresif. Di sini, ekspresifitas menderita, karena penggunaan yang tepat
using
adalah untuk menunjukkan bahwa di belakang, ada sumber daya, seperti aliran, koneksi jaringan atau database yang harus dirilis tanpa menunggu pengumpul sampah.
sumber
using
: Pernyataan yang terakhir (misalnyaprofiler.Stop(p)
) tidak dijamin akan dieksekusi dalam menghadapi pengecualian dan aliran kontrol.Jawaban:
Pernyataan terakhir Anda - bahwa "penggunaan penggunaan yang tepat adalah untuk menunjukkan bahwa di belakang, ada sumber daya, seperti aliran, koneksi jaringan atau database yang harus dirilis tanpa menunggu pengumpul sampah" salah, dan alasan mengapa diberikan pada dokumentasi untuk antarmuka IDisposable: http://msdn.microsoft.com/en-us/library/system.idisposable.aspx
Jadi, jika kelas Anda menggunakan sumber daya yang tidak dikelola, tidak masalah ketika Anda mungkin atau mungkin tidak ingin GC terjadi - itu tidak ada hubungannya dengan GC karena sumber daya yang tidak dikelola tidak GC'ed ( https: // stackoverflow. com / pertanyaan / 3607213 / apa-yang-dimaksud-oleh-dikelola-vs-tidak dikelola-sumber daya-in-net ).
Jadi tujuan "menggunakan" bukan untuk menghindari menunggu di GC, itu untuk memaksa rilis sumber daya yang tidak dikelola sekarang , sebelum instance kelas keluar dari ruang lingkup dan itu Finalisasi disebut. Ini penting untuk alasan yang harus jelas - sumber daya yang tidak dikelola mungkin memiliki ketergantungan pada sumber daya yang tidak dikelola lainnya, dan jika sumber daya tersebut dibuang (atau diselesaikan) dalam urutan yang salah, Hal Buruk dapat terjadi.
Jadi, jika kelas yang sedang diinvestasikan dalam blok menggunakan menggunakan sumber daya yang tidak dikelola, maka jawabannya adalah ya - itu tepat.
Perhatikan bahwa IDisposable tidak bersifat preskriptif tentang hal itu hanya untuk melepaskan sumber daya yang tidak dikelola, hanya saja ini tujuan utamanya . Ini mungkin menjadi kasus bahwa penulis kelas memiliki beberapa tindakan yang mereka ingin menegakkan terjadi pada waktu tertentu, dan menerapkan IDisposable mungkin cara untuk mendapatkan itu terjadi, tapi apakah atau tidak itu solusi elegan adalah sesuatu yang dapat hanya dijawab berdasarkan kasus per kasus.
Apapun, penggunaan "menggunakan" menyiratkan bahwa kelas mengimplementasikan IDisposable, sehingga tidak melanggar ekspresi kode; itu membuatnya sangat jelas apa yang sebenarnya terjadi.
sumber
Penggunaan
using
menyiratkan adanya suatuDispose()
metode. Pemrogram lain akan menganggap bahwa metode semacam itu ada pada objek. Konsekuensinya, jika suatu objek tidak dapat dibuang, Anda sebaiknya tidak menggunakannyausing
.Kejelasan kode adalah raja. Baik menghilangkan
using
, atau mengimplementasikanIDisposable
objek.MiniProfiler tampaknya digunakan
using
sebagai mekanisme untuk "memagari" kode yang diprofilkan. Ada beberapa manfaat untuk ini; mungkin, MiniProfiler sedang memanggilDispose()
untuk menghentikan timer, atau timer dihentikan ketika objek MiniProfiler keluar dari ruang lingkup.Secara umum, Anda akan dipanggil
using
ketika semacam finalisasi perlu terjadi secara otomatis. Dokumentasi untukhtml.BeginForm
menyatakan bahwa, ketika metode ini digunakan dalamusing
pernyataan, itu membuat</form>
tag penutup di akhirusing
blok.Itu tidak berarti itu masih bukan penyalahgunaan.
sumber
IDisposable
/Dispose()
meskipun tidak memiliki apa pun untuk dibuang dalam arti yang digambarkan OP?Dispose
diperlukan untukusing
masuk akal sama sekali (terlepas dari apakah itu sesuai). Semua contoh OP diterapkanDispose
, bukan? Dan IIUC, pertanyaannya adalah apakah benar bahwa kelas-kelas ini digunakanDispose
, daripada beberapa metode lain (sepertiStop()
untuk MiniProfiler).using
adalah kesalahan dan pengecualian aman. Itu memastikanDispose()
akan dipanggil terlepas dari kesalahan yang dibuat programmer. Ini tidak mengganggu penangkapan atau penanganan pengecualian, tetapiDispose()
metode ini dijalankan secara rekursif ke tumpukan ketika pengecualian dilemparkan.Objek yang mengimplementasikan
IDispose
tetapi tidak memiliki apa pun untuk dibuang saat selesai. Paling-paling, masa depan membuktikan desain mereka. Sehingga Anda tidak perlu memperbaiki kode sumber Anda, ketika di masa depan, mereka perlu membuang sesuatu.sumber