Burada eksik x
olan şey, derleyicinin tanımlandığı yöntemin sonuna kadar değişkeninizin ömrünü uzatmasıdır - bu sadece derleyicinin yaptığı bir şeydir - ancak bunu sadece bir DEBUG derlemesi için yapar.
Kodu, değişkeni ayrı bir yöntemde tanımlanacak şekilde değiştirirseniz, beklediğiniz gibi çalışır.
Aşağıdaki kodun çıktısı:
False
True
Ve kod:
using System;
namespace ConsoleApp1
{
class Finalizable
{
~Finalizable()
{
_extendMyLifetime = this;
}
public static bool LifetimeExtended => _extendMyLifetime != null;
static Finalizable _extendMyLifetime;
}
class Program
{
public static void Main()
{
test();
Console.WriteLine(Finalizable.LifetimeExtended); // False.
GC.Collect();
GC.WaitForPendingFinalizers();
Console.WriteLine(Finalizable.LifetimeExtended); // True.
}
static void test()
{
new Finalizable();
}
}
}
Yani temelde anlayış doğru, ama sen kadar sinsi derleyici sizin değişken canlı tutmak için gittiğini bilmiyordu sonra aradığınız GC.Collect()
- Açıkça boş olarak ayarlayın bile!
Yukarıda belirttiğim gibi, bu sadece bir DEBUG derlemesi için olur - muhtemelen yöntemin sonuna kadar hata ayıklarken yerel değişkenlerin değerlerini inceleyebilirsiniz (ancak bu sadece bir tahmin!).
Özgün kod, bir sürüm derlemesi için beklendiği gibi çalışır - bu nedenle, aşağıdaki kod false, true
RELEASE derlemesi ve false, false
DEBUG derlemesi için çıkar:
using System;
namespace ConsoleApp1
{
class Finalizable
{
~Finalizable()
{
_extendMyLifetime = this;
}
public static bool LifetimeExtended => _extendMyLifetime != null;
static Finalizable _extendMyLifetime;
}
class Program
{
public static void Main()
{
new Finalizable();
Console.WriteLine(Finalizable.LifetimeExtended); // False.
GC.Collect();
GC.WaitForPendingFinalizers();
Console.WriteLine(Finalizable.LifetimeExtended); // True iff RELEASE build.
}
}
}
Ek olarak: Sonlandırılmakta olan nesneye yapılan başvurunun bir program kökünden erişilebilmesine neden olan bir sınıf için sonlandırıcıda bir şey yaparsanız, o nesne artık olmadıkça ve yapılmadıkça o nesnenin çöp toplanmayacağını unutmayın. başvurulan.
Başka bir deyişle, bir nesneye sonlandırıcı aracılığıyla "yürütmenin durdurulması" verebilirsiniz. Bu genellikle kötü bir tasarım olarak kabul edilir!
Örneğin _extendMyLifetime = this
, sonlandırıcıda yaptığımız yukarıdaki kodda , nesneye yeni bir referans oluşturuyoruz, bu yüzden artık _extendMyLifetime
(ve başka bir referans) artık referans verene kadar çöp toplanmayacak .
Person1
Nedir? Sadece görüyorumPerson
. Sonuncu: sonlandırıcıların nasıl çalıştığı hakkında docs.microsoft.com/dotnet/csharp/programming-guide/… adresine bakın .