Kelas seperti Stream
, StreamReader
, StreamWriter
dll mengimplementasikan IDisposable
interface. Itu berarti, kita dapat memanggil Dispose()
metode pada objek dari kelas-kelas ini. Mereka juga mendefinisikan public
metode yang disebut Close()
. Sekarang membingungkan saya, seperti apa yang harus saya panggil setelah saya selesai dengan benda? Bagaimana jika saya memanggil keduanya?
Kode saya saat ini adalah:
using (Stream responseStream = response.GetResponseStream())
{
using (StreamReader reader = new StreamReader(responseStream))
{
using (StreamWriter writer = new StreamWriter(filename))
{
int chunkSize = 1024;
while (!reader.EndOfStream)
{
char[] buffer = new char[chunkSize];
int count = reader.Read(buffer, 0, chunkSize);
if (count != 0)
{
writer.Write(buffer, 0, count);
}
}
writer.Close();
}
reader.Close();
}
}
Seperti yang Anda lihat, saya telah menulis using()
konstruk, yang secara otomatis memanggil Dispose()
metode pada setiap objek. Tapi saya juga menyebut Close()
metode. Apakah tepat?
Tolong sarankan saya praktik terbaik saat menggunakan objek aliran. :-)
Contoh MSDN tidak menggunakan using()
konstruk, dan memanggil Close()
metode:
Apakah itu baik?
using (MemoryStream ms1 = new MemoryStream(), ms2 = new MemoryStream()) { }
. Maksud saya seperti ini di mana Anda dapat mendefinisikan kembali tipe:using (MemoryStream ms = new MemoryStream()) using (FileStream fs = File.OpenRead("c:\\file.txt")) { }
Jawaban:
Lompatan cepat ke Reflector.NET menunjukkan bahwa
Close()
metode aktifStreamWriter
adalah:Dan
StreamReader
adalah:The
Dispose(bool disposing)
menimpa diStreamReader
yaitu:The
StreamWriter
Metode ini mirip.Jadi, membaca kode jelas bahwa Anda dapat memanggil
Close()
&Dispose()
pada streaming sesering mungkin dan dalam urutan apa pun. Itu tidak akan mengubah perilaku dengan cara apa pun.Jadi turun ke apakah lebih mudah digunakan
Dispose()
,Close()
dan / atauusing ( ... ) { ... }
.Preferensi pribadi saya adalah yang
using ( ... ) { ... }
harus selalu digunakan bila memungkinkan karena membantu Anda untuk "tidak lari dengan gunting".Tapi, meski ini membantu ketepatan, hal itu mengurangi keterbacaan. Di C # kita sudah memiliki banyak penutupan kurung kurawal jadi bagaimana kita tahu yang mana yang benar-benar melakukan penutupan di sungai?
Jadi saya pikir yang terbaik adalah melakukan ini:
Itu tidak mempengaruhi perilaku kode, tetapi itu membantu keterbacaan.
sumber
Close()
panggilan yang berlebihan itu . Jika seseorang yang kurang berpengalaman melihat kode dan tidak tahu tentangusing
dia akan: 1) mencarinya dan belajar , atau 2) menambahkanClose()
secara manual buta . Jika dia memilih 2), mungkin beberapa pengembang lain akan melihat berlebihanClose()
dan bukannya "terkekeh", menginstruksikan pengembang yang kurang berpengalaman. Saya tidak mendukung menyulitkan pengembang yang belum berpengalaman, tetapi saya mendukung untuk mengubahnya menjadi pengembang yang berpengalaman.Tidak, Anda tidak harus memanggil metode-metode itu secara manual. Pada akhir
using
blokDispose()
metode ini disebut secara otomatis yang akan membebaskan sumber daya yang tidak dikelola (setidaknya untuk kelas .NET BCL standar seperti stream, pembaca / penulis, ...). Jadi, Anda juga bisa menulis kode seperti ini:The
Close()
metode panggilanDispose()
.sumber
using
yang pertamaresponseStream
karena dibungkus olehreader
yang akan memastikan ditutup ketika pembaca dibuang. +1 nonthelessThe Close method calls Dispose.
.. dan di sisa posting Anda, Anda menyiratkan ituDispose()
akan meneleponClose()
, saya tidak boleh menelepon yang terakhir secara manual. Apakah Anda mengatakan mereka saling memanggil?using
blok. Saya menerapkan kelas yang menulis dari waktu ke waktu dan karena itu tidak bisa.using
(atau, sekali lagi, pilih Pola Buang).Dokumentasi mengatakan bahwa kedua metode ini setara:
Jadi, keduanya sama-sama valid:
Secara pribadi, saya akan tetap dengan opsi pertama, karena mengandung lebih sedikit "noise".
sumber
Pada banyak kelas yang mendukung keduanya
Close()
danDispose()
metode, dua panggilan akan setara. Namun, pada beberapa kelas, dimungkinkan untuk membuka kembali objek yang telah ditutup. Beberapa kelas semacam itu dapat menjaga beberapa sumber daya tetap hidup setelah Tutup, untuk mengizinkan pembukaan kembali; yang lain mungkin tidak menjaga sumber daya apa pun tetap hidupClose()
, tetapi mungkin menetapkan benderaDispose()
untuk secara eksplisit melarang pembukaan kembali.Kontrak untuk
IDisposable.Dispose
secara eksplisit mensyaratkan bahwa memanggilnya pada suatu objek yang tidak akan pernah digunakan lagi akan paling tidak berbahaya, jadi saya akan merekomendasikan memanggil salah satuIDisposable.Dispose
atau metode yang dipanggilDispose()
pada setiapIDisposable
objek, apakah seseorang juga memanggil atau tidakClose()
.sumber
Ini adalah pertanyaan lama, tetapi sekarang Anda dapat menulis menggunakan pernyataan tanpa harus memblokir masing-masing. Mereka akan dibuang dalam urutan terbalik ketika blok yang mengandung selesai.
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-8.0/using
sumber