यहां जो चीज आपको याद आ रही है वह यह है कि कंपाइलर आपके xवैरिएबल के जीवनकाल का विस्तार उस विधि के अंत तक कर रहा है जिसमें यह परिभाषित किया गया है - कि कंपाइलर केवल कुछ करता है - लेकिन यह केवल डेबग बिल्ड के लिए करता है।
यदि आप कोड को बदलते हैं ताकि चर एक अलग विधि में परिभाषित हो, तो यह आपकी अपेक्षा के अनुरूप काम करेगा।
निम्नलिखित कोड का आउटपुट है:
False
True
और कोड:
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();
}
}
}
तो मूल रूप से आपकी समझ सही थी, लेकिन आप नहीं जानते थे कि डरपोक कंपाइलर आपके चर को जीवित रखने वाला था जब तक कि आपको फोन नहीं किया जाता GC.Collect()- भले ही आपने इसे स्पष्ट रूप से शून्य करने के लिए सेट किया हो!
जैसा कि मैंने ऊपर उल्लेख किया है, यह केवल डेबग बिल्ड के लिए होता है - संभवतः इसलिए आप विधि के अंत में डिबगिंग करते समय स्थानीय चर के लिए मानों का निरीक्षण कर सकते हैं (लेकिन यह सिर्फ एक अनुमान है!)।
मूल कोड एक रिलीज बिल्ड के लिए अपेक्षित के रूप में काम करता है - इसलिए निम्नलिखित कोड false, trueएक निर्माण के लिए और false, falseएक DEBUG के लिए आउटपुट :
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.
}
}
}
एक परिशिष्ट के रूप में: ध्यान दें कि यदि आप किसी वर्ग के लिए अंतिम रूप से ऐसा कुछ करते हैं जिसके कारण किसी वस्तु को अंतिम रूप दिया जा सकता है, तो वह प्रोग्राम रूट से पहुंच योग्य नहीं होगी, तो वह वस्तु तब तक कचरा-संग्रहित नहीं होगी जब तक कि वह वस्तु अब नहीं है संदर्भित किया है।
दूसरे शब्दों में, आप किसी फ़ाइनलीज़र के माध्यम से किसी वस्तु को "निष्पादन पर रोक" दे सकते हैं। यह आमतौर पर एक बुरा डिज़ाइन माना जाता है, हालाँकि!
उदाहरण के लिए, ऊपर दिए गए कोड में, जहां हम _extendMyLifetime = thisफाइनल में करते हैं, हम ऑब्जेक्ट के लिए एक नया संदर्भ बना रहे हैं, इसलिए यह अब कचरा एकत्र नहीं किया जाएगा _extendMyLifetime(और किसी भी अन्य संदर्भ) अब इसे संदर्भित नहीं करता है।
Person1? मैं ही देखता हूंPerson। अंतिम: कैसे अंतिम रूप देने के लिए docs.microsoft.com/dotnet/csharp/programming-guide/… देखें ।