Soru Tek kullanımlık bir nesneyi satır içi oluşturmak ve kullanmak güvenli midir?


Tek kullanımlık bir nesneyi kullanarak birçok kez geliştiriciyi gördüm İşte Örneğin. Satır içi demek istediğim:

var result = new DataTable().Compute("1 + 4 * 7", null);

Bunu biliyorum Dispose yöntem çağrılmayacak, ancak nesneye herhangi bir referans yapılmadığından, çöp toplayıcısının bunu nasıl ele alacağı? Tek kullanımlık bir nesneyi kullanmak güvenli midir?

Kullandım DataTable Benim örneğimde, bulduğum tek somut örnek olduğu için, benim sorum genel olarak tek kullanımlık nesneler için geçerli. Ben bunları kişisel olarak kullanmıyorum, sadece bu şekilde kullanılmışlarsa GC tarafından farklı şekilde ele alındıklarını bilmek istedim.


17
2018-04-23 21:11


Menşei


Bu genel sorunuza cevap vermese de, sizin örneğinizle konuşur. stackoverflow.com/questions/913228/... - hatchet
Bu snippet, DataTable'ın tek kullanımlık bir şeye sahip olmadığını ve aslında Dispose () uygulamasını uygulamadığını bilen akıllı bir programcı tarafından yazılmıştır. .NET programcılarının çoğu bu konuda çok rahatsızlar. Öyleyse bunu böyle yapmayın, kullandığınızda çok fazla çirkinleşmez. kullanma Beyan. Asla yanılma konusunda iyi hissedebilirsiniz. - Hans Passant


Cevaplar:


Buradaki temel sorun, zamanlamadır. Dispose örneğinizde sadece bilinmeyen denir (iyi bir uygulama sağlayarak IDisposable - aşağıya bakınız). Kullanmayı düşünürdüm IDisposable örneği olmayan using bir kod kokusu bildirir. Sınıfı uyguluyor IDisposable bir sebepten ötürü, bir kullanıcı sizin sözleşmenize uymak zorundasınız.

Ancak, şunu unutmayın: doğru uygulama arasında IDisposable class'es finalizer, atılmamış bir nesnenin bertaraf edilmesini sağlar. Bu yüzden bile değil içinde örneği usingBertaraf işlemi yapılmalı, ancak bilinmeyen zamanda ve farklı bir şekilde (GC'ler) işlenecektir.

Sadece bu şekilde kullanılmışlarsa, GC tarafından farklı şekilde ele alındıklarını bilmek istedim.

Hayır, GC tüm nesnelere benzer davranır ve tedavi etmez. IDisposable uygulamalar farklı şekilde. Ancak, doğru bir implementasyonda IDisposable  Finalize yöntem (nesne başına temelinde basılmadıkça her nesne için GC tarafından çağrılır) çağrısı, Dispose.


11
2018-04-23 21:18



Katılıyorum. Açıkça atmamak için nispeten zararsız olduğu bazı sınıflar olsa da, gelişmesi çok zayıf bir alışkanlık gibi görünüyor. - hatchet


Satırda başlatılan nesnenin bir yıkıcı uygulanmışsa, nesne yok sayıldıktan sonra bu yıkıcı Dispose () öğesini çağırıyor olabilir.

Bununla birlikte, daha temiz ve doğru yol bir kullanım ifadesi kullanmaktır; çünkü bu, herhangi bir amaç için etrafta asılı duran nesnelerin yalnızca örneklerine yol açabilir.


1
2018-04-23 21:17



C # nesneleri yıkıcılara sahip değildir. Onlar Mayıs ayı finalizörler var. Nesneler kapsam dışına çıktığında, finalizer'lar çalışmaz. GC, onları çalıştırma zamanı olduğunu düşündüğünde çalışırlar. - GSerg
Benimle dalga mı geçiyorsun? msdn.microsoft.com/en-us/library/66x5fx1b.aspx - Dmitry K.
Bağlantınızdan: "Programcı, çöp toplayıcı tarafından belirlendiğinden, kontrolörün hiçbir kontrolü yoktur. Çünkü bu, çöp toplayıcı tarafından belirlenir." - Poul Bak
Ayrıca, sınıfın bir finalizer (C # terminolojisinde bir yıkıcı) varsa, çöp toplayıcının bir sonraki jenerasyon 0'da bu örneği derhal toplamayacağını unutmayın. Bunun yerine örneği bir finalizer sırası ve gelecek nesil-1 toplanana kadar bu örneği toplamayı bitirmeyecek. Bu nedenle, sonlandırıcıya (yıkıcı) bağlı olarak, var olduğunu ve doğru bir şekilde uygulandığını bilseniz bile, bir performans isabetine yol açabilir. Ayrıca, diğerlerinin söylediği gibi, olası kaynak koleksiyonlarının oluşmasını beklemek yerine, bu kaynakları şimdi serbest bırakmak en iyisidir. - Jeppe Stig Nielsen
@ruakh İyi soru! Sanırım bunu Dispose() yöntem denir GC.SuppressFinalize(this). Bir yıkıcı olduğunda, durum böyle olmalıdır. Bu durumda bir çağrı Dispose() derhal toplanmasını ve kesinleştirme kuyruğunun yapılmasını sağlayacaktır. Kesinleştirme açıkça böyle bir şekilde bastırılmazsa, kesinlikle haklısınız: performans vuruşu her iki şekilde de vardır. İnsanlar çoğu zaman bir yıkıcının sadece varlığına şaşırırlar. boş bir gövdede bile, performansı acıtıyor. - Jeppe Stig Nielsen


Bu şekilde tek kullanımlık nesneler kullanmak güvenli değildir. Evet, hiçbir başvuru yapılmayacak, ancak Tek kullanımlık modelin amacı, toplanmamış olan çöp toplanamayan tüm kaynakları (OS tutamaçları gibi) bertaraf etmektir.


1
2018-04-23 21:18



Yönetilmeyen kaynaklar, açık bir çağrıyla daha önce elden çıkarılmadığı takdirde çöp toplama sırasında serbest bırakılacak IDisposable.Dispose(). Tabii ki, bu varsayar ki IDisposable doğru şekilde uygulanır ve sonlandırıcı yönetilmeyen kaynağı serbest bırakır. Bu nedenle, daha uzun süre kullanılmadığında tek kullanımlık bir nesneyi atmamak ve onu temizlemek için çöp toplayıcıya bırakmamak aslında "güvenli" dir. Ancak, çok akıllı veya verimli değildir. - Martin Liversage