Bir sınıf tasarlarken ortak programlama pratiğine göre davranış tutarlılığı tercih edilmelidir mi? Belirli bir örnek vermek gerekirse:
Yaygın bir kural şudur: Bir sınıfın bir nesnesi varsa (örneğin, onu yarattıysa), tamamlandıktan sonra onu temizlemekten sorumludur. .NET'te belirli bir örnek, sınıfınız bir IDisposable
nesneye sahipse nesneyi ömrünün sonunda atması gerektiğidir. Ve eğer ona sahip değilseniz, dokunmayın.
Şimdi .NET'teki StreamWriter
sınıfa bakarsak, belgelendirmede, kapalı / atıldığında temel akışı kapattığını bulabiliriz. Bu, StreamWriter
yazar temel dosya akışını oluşturduğundan ve bu nedenle onu kapatması gerektiğinde bir dosya adının iletilmesiyle başlatılması durumunda gereklidir . Bununla birlikte, yazarın da kapattığı harici bir akıştan geçebilir.
Bu beni birçok kez rahatsız etti (evet, kapamayan bir sarıcı yapabileceğinizi biliyorum ama bu nokta değil), ancak görünüşe göre Microsoft, nereden olursa olsun akışı her zaman kapatmanın daha tutarlı olduğuna karar verdi.
Sınıflarımdan birinde böyle bir desenle karşılaştığımda, genellikle yapıcı aracılığıyla enjekte edilen ownsFooBar
durumlarda yanlış olarak ayarlanan FooBar
ve aksi takdirde doğru olan bir bayrak oluştururum . Bu şekilde, temizlik görevini, örneği açıkça geçtiğinde arayan kişiye iletir.
Şimdi merak ediyorum belki de tutarlılık en iyi uygulamadan yana mı olmalı (ya da belki de en iyi uygulamam o kadar iyi değil)? Buna karşı / ona karşı argüman var mı?
Açıklama için düzenleyin
"Tutarlılık" ile demek istediğim: Sınıfın tutarlı davranışı her zaman yalnızca bir nesne oluşturduysanız veya sahipliğini açıkça aktardıysanız, bir nesnenin sahipliğini almak için her zaman sahiplik alan (ve akışı kapatma) ve "en iyi uygulama" ya karşıdır.
Enoying olduğu bir örneğe gelince:
Bazı verileri oluşturmak ve işlemek gibi, onunla bir şeyler yapmak için bir akışı kabul eden iki belirli sınıfınız (bazı 3. taraf kütüphanelerinden) olduğunu varsayın:
public class DataProcessor
{
public Result ProcessData(Stream input)
{
using (var reader = new StreamReader(input))
{
...
}
}
}
public class DataSource
{
public void GetData(Stream output)
{
using (var writer = new StreamWriter(output))
{
....
}
}
}
Şimdi şöyle kullanmak istiyorum:
Result ProcessSomething(DataSource source)
{
var processor = new DataProcessor();
...
var ms = new MemoryStream();
source.GetData(ms);
return processor.ProcessData(ms);
}
Bu Cannot access a closed stream
, veri işlemcide bir istisna dışında başarısız olur . Biraz yapılıdır ama konuyu açıklamalıdır. Bunu düzeltmenin çeşitli yolları var ama yine de yapmamam gereken bir şey üzerinde çalıştığımı hissediyorum.