2016-11-28 25 views
5

Dispose (Desen) desenini uygularken, nesne atıldıktan sonra nesnenin özellikleri ObjectDisposedException öğesini atmalıdır.ObjectDisposedException özelliğini kullanma

Her özellik ve yöntem, dizinin başlangıcında bir kod satırına sahipse ve bu istisnayı yalnızca ThrowIfDisposed() 'a atmak gerekirse, birçok yinelenen kod gibi görünüyor. 80 tekrarlanan satır olan 40 mülkünüz varsa. Büyük bir sınıfta çok hızlı ekleyebilir.

Daha iyi bir yol bulamadım bu yüzden öyle görünüyor, ancak böyle bir şey istediğimi düşündüm. Daha iyi bir yolu var mı?

+0

Tek kullanımlık desen, .NET 1.x hatasıydı, kurtulmak çok zordu. SafeHandle sınıflarında uygulanan kritik finalizatörler ile .NET 2.0'da iyice düzeltildi. Model için geriye kalan tek kullanım, temel sınıfın onu uygulayarak sizi bununla başa çıkmaya zorlamasıdır. Kodunuzu atarla bilerek daha iyi yapmazsınız, sadece istisnai atmak için temel sınıfa güvenirsiniz. –

+0

Yorumlarınız için teşekkür ederiz. SafeHandle sınıfına bakmam gerekecek. Tek kullanımlık modeli hiç sevmedim ve daha iyi bir yedek bulmayı çok isterim. – JHJ

cevap

7

Tek bir sınıfta 40 mülkünüz varsa, büyük olasılıkla bir tasarım sorununuz var, ancak devam edersiniz ... Bu, belirli kullanım durumuna bağlıdır, ancak yalnızca ObjectDisposedException öğesini atmanız gerekir. Aslında sınıf çözülmüş olduğu için çözülmelidir. Somut bir örnek vermek gerekirse: Burada

public class MyStream : IDisposable 
{ 
    private string name; 
    private Stream stream; 

    public MyStream(string name) 
    { 
     this.Name = name; 
     this.Stream = new FileStream(...); 
    } 

    public string Name 
    { 
     get 
     { 
      return this.name; 
     } 
    } 

    public Stream Stream 
    { 
     get 
     { 
      if (this.IsDisposed) 
      { 
       throw new ObjectDisposedException(); 
      } 

      return this.stream; 
     } 
    } 

    private bool IsDisposed { get; set; } 

    public void Dispose() 
    { 
     if (!this.IsDisposed) 
     { 
      this.IsDisposed = true; 
      this.Stream.Dispose(); 
      this.Stream = null; 
     } 
    } 
} 

, altta yatan akışı bertaraf edildiği için mülk Stream bir istisna atar, bu nedenle artık kullanılamaz. Ancak Name'un atması için bir sebebi yok. Gerçek sorunlu özelliğine erişimin istisna atar Oradan birçok durumda, kodunuzu çarpanlara edebilirsiniz:

public int Length 
{ 
    get 
    { 
     // Since we access the Stream property, the ObjectDisposedException 
     // will be thrown when the class is disposed 
     return this.Stream.Length; 
    } 
} 

hala bile bu modeli izledikten sonra süslemek için çok fazla özelliklere sahip olursa, derleme zamanında bir davranış enjekte etmenizi sağlayan Fody gibi kütüphaneleri kullanabilirsiniz. Bunu kullanarak, özelliklerde gerektiği gibi uyguladığınız bir [ThrowIfDisposed] özniteliği oluşturabilirsiniz.

+1

40+ mülkün çok olduğu ve normalde bunun çok fazla tek bir sınıfa ayrılmasının gerektiği, ancak ayrılmasının tek yol olduğu anlamına geldiğine katılıyorum. Excel bir örnektir. Onunla çalışmak bu soruyu sormamı istedi. Örneğin, Range sınıfında 99 özellik ve 87 yöntem vardır. .NET'ten COM ile çalışmak, bir ** bir acıdır. Nesne bertaraf edildikten ve tüm excel kaynağı serbest kaldığında excel kullanan herhangi bir özellik veya yöntem boş gösterici istisnaları atar. Görünmez gibi görünüyor ama belki sadece bu boş gösterici istisnalara izin vermek bu durumda çözümdür. – JHJ

0

Kontrol diğer konu: Handling ObjectDisposedException correctly in an IDisposable class hierarchy

Sen istisna :IDisposable uygulayan sınıfın her zaman birileri erişim özelliği atmak gerekmez. Yalnızca, atılması gereken nesneyi (örneğin, yazma/dosyalara okuma, ağ soketlerine erişme, ..) erişiyorsanız gereklidir. Diğer tüm durumlar için, sadece fikir normal sınıf ile gidebilirsiniz. > Bu :IDisposable sadece bir kısmını yapmak için izin verecek olan ve geri kalan IDisposable bağımsız olacak - orada daha sınıflar arasında onları bölmek seçenektir olarak

Normalde nesneler/sınıfları özellikleri bu sayıda yok sınıf.

İlgili konular