Yanıtlar:
Bazılarının genel olarak işaret ettiği gibi, bu bir sorun değildir.
Sorunlara neden olacak tek durum, bir using ifadesinin ortasına dönüp ek olarak in using değişkenini döndürmenizdir. Ama sonra tekrar, geri dönmediyseniz ve bir değişkene bir referans tuttuğunuzda bile sorunlara neden olur.
using ( var x = new Something() ) {
// not a good idea
return x;
}
Tıpkı kötü
Something y;
using ( var x = new Something() ) {
y = x;
}
return
deyim using
bloğun sonuna herhangi bir kod yolu ile erişilemez olur. using
Gerekirse nesnenin atılabilmesi için bloğun ucunun çalıştırılması gerekir.
Tamamen iyi.
Görünüşe göre bunu düşünüyorsun
using (IDisposable disposable = GetSomeDisposable())
{
//.....
//......
return Stg();
}
körü körüne çevrildi:
IDisposable disposable = GetSomeDisposable()
//.....
//......
return Stg();
disposable.Dispose();
Ki, kuşkusuz, bir sorun olacağını ve yapacak using
işte bu yüzden hangi --- deyimi oldukça anlamsız değil ne yaptığını.
Derleyici, bloktan nasıl ayrılacağından bağımsız olarak, kontrol bloktan ayrılmadan önce nesnenin atılmasını sağlar.
Kesinlikle iyi - hiç sorun değil. Neden yanlış olduğuna inanıyorsun?
Kullanım ifadesi, bir try / nihayet bloğu için sadece sözdizimsel şekerdir ve Grzenio'nun dediği gibi bir try bloğundan geri dönmenin iyi olduğunu.
Dönüş ifadesi değerlendirilir, son olarak blok yürütülür, sonra yöntem geri döner.
Bu tamamen kabul edilebilir. Bir kullanarak deyim ıdisposable nesne ne olursa olsun bertaraf edilecektir sağlar.
Gönderen MSDN :
Using ifadesi, nesne üzerindeki yöntemleri çağırırken özel durum oluşsa bile Dispose'in çağrılmasını sağlar. Aynı sonucu, nesneyi bir try bloğunun içine koyarak ve sonunda bir blokta Dispose (Çağır) olarak çağırarak da elde edebilirsiniz; aslında, using ifadesi derleyici tarafından bu şekilde çevrilir.
Feryat kodu nasıl using
çalıştığını gösterir :
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());
}
Çıktı:
't1' oluşturulur.
't2' oluşturulur.
't3' oluşturulur.
'T1, t2, t3'ten yaratıldı' oluşturulur.
't3' atılmıştır.
't2' atılmıştır.
't1' atılır.
İmha edilenler return ifadesinden sonra ancak işlevin çıkışından önce çağrılır.
Belki de bunun kabul edilebilir olduğu% 100 doğru değil ...
Kullanıcıları iç içe geçiriyor ve iç içe geçmişten geri dönüyorsanız, güvenli olmayabilir.
Bunu örnek olarak alalım:
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();
}
}
}
Ben csv olarak çıktı için bir DataTable geçiriyordu. Ortadaki dönüşle, tüm satırları akışa yazıyordu, ancak çıktılanan csv'de her zaman bir satır eksikti (veya arabellek boyutuna bağlı olarak). Bu bana bir şeyin düzgün bir şekilde kapatılmadığını söyledi.
Doğru yol, önceki tüm kullanıcıların doğru bir şekilde atıldığından emin olmaktır:
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();
}