Jawaban:
Seperti yang ditunjukkan beberapa orang secara umum, ini bukan masalah.
Satu-satunya kasus itu akan menyebabkan Anda masalah adalah jika Anda kembali di tengah pernyataan menggunakan dan juga mengembalikan variabel menggunakan. Tetapi sekali lagi, ini juga akan menyebabkan Anda masalah bahkan jika Anda tidak kembali dan hanya menyimpan referensi ke variabel.
using ( var x = new Something() ) {
// not a good idea
return x;
}
Sama buruknya
Something y;
using ( var x = new Something() ) {
y = x;
}
return
pernyataan membuat akhir using
blok tidak dapat diakses oleh jalur kode apa pun. Ujung using
blok perlu dijalankan sehingga objek dapat dibuang jika diperlukan.
Tidak apa-apa.
Anda tampaknya memikirkan itu
using (IDisposable disposable = GetSomeDisposable())
{
//.....
//......
return Stg();
}
diterjemahkan secara membabi buta ke:
IDisposable disposable = GetSomeDisposable()
//.....
//......
return Stg();
disposable.Dispose();
Yang, diakui, akan menjadi masalah, dan akan membuat using
pernyataan itu agak sia-sia --- itulah sebabnya bukan itu yang dilakukannya.
Compiler memastikan bahwa objek dibuang sebelum kontrol meninggalkan blok - terlepas dari bagaimana ia meninggalkan blok.
Tidak apa-apa - tidak ada masalah sama sekali. Mengapa Anda percaya itu salah?
Pernyataan menggunakan hanyalah gula sintaksis untuk blok percobaan / akhirnya, dan seperti yang dikatakan Grzenio, tidak apa-apa untuk kembali dari blok percobaan juga.
Ekspresi pengembalian akan dievaluasi, maka blok akhirnya akan dieksekusi, maka metode akan kembali.
Itu benar-benar dapat diterima. Sebuah menggunakan pernyataan memastikan obyek IDisposable akan dibuang tidak peduli apa.
Dari MSDN :
Pernyataan menggunakan memastikan Buang dipanggil bahkan jika pengecualian terjadi saat Anda memanggil metode pada objek. Anda dapat mencapai hasil yang sama dengan meletakkan objek di dalam blok coba lalu memanggil Buang di akhirnya blok; sebenarnya, ini adalah bagaimana pernyataan penggunaan diterjemahkan oleh kompiler.
Kode di bawah ini menunjukkan cara using
kerjanya:
private class TestClass : IDisposable
{
private readonly string id;
public TestClass(string id)
{
Console.WriteLine("'{0}' is created.", id);
this.id = id;
}
public void Dispose()
{
Console.WriteLine("'{0}' is disposed.", id);
}
public override string ToString()
{
return id;
}
}
private static TestClass TestUsingClose()
{
using (var t1 = new TestClass("t1"))
{
using (var t2 = new TestClass("t2"))
{
using (var t3 = new TestClass("t3"))
{
return new TestClass(String.Format("Created from {0}, {1}, {2}", t1, t2, t3));
}
}
}
}
[TestMethod]
public void Test()
{
Assert.AreEqual("Created from t1, t2, t3", TestUsingClose().ToString());
}
Keluaran:
't1' dibuat.
't2' dibuat.
't3' dibuat.
'Dibuat dari t1, t2, t3' dibuat.
't3' dibuang.
't2' dibuang.
't1' dibuang.
Yang dibuang dipanggil setelah pernyataan kembali tetapi sebelum keluar dari fungsi.
Mungkin tidak 100% benar bahwa ini dapat diterima ...
Jika Anda kebetulan menggunakan sarang dan kembali dari sarang, mungkin itu tidak aman.
Ambil ini sebagai contoh:
using (var memoryStream = new MemoryStream())
{
using (var textwriter = new StreamWriter(memoryStream))
{
using (var csv = new CsvWriter(textwriter))
{
//..write some stuff to the stream using the CsvWriter
return memoryStream.ToArray();
}
}
}
Saya melewati DataTable untuk di-output sebagai csv. Dengan kembalinya di tengah, itu menulis semua baris ke aliran, tetapi csv yang dihasilkan selalu hilang satu baris (atau beberapa, tergantung pada ukuran buffer). Ini memberi tahu saya bahwa ada sesuatu yang tidak ditutup dengan benar.
Cara yang benar adalah memastikan semua penggunaan sebelumnya dibuang dengan benar:
using (var memoryStream = new MemoryStream())
{
using (var textwriter = new StreamWriter(memoryStream))
{
using (var csv = new CsvWriter(textwriter))
{
//..write some stuff to the stream using the CsvWriter
}
}
return memoryStream.ToArray();
}