Computer >> कंप्यूटर ट्यूटोरियल >  >> प्रोग्रामिंग >> C#

C# में IDisposable डिज़ाइन पैटर्न कैसे लागू करें

जब हमें अनमैनेज्ड ऑब्जेक्ट्स को डिस्पोज़ करने की आवश्यकता होती है तो हमें IDisposable डिज़ाइन पैटर्न (या डिस्पोज़ पैटर्न) का उपयोग करना चाहिए।

IDisposable डिज़ाइन पैटर्न को लागू करने के लिए, वह क्लास जो अनमैनेज्ड ऑब्जेक्ट्स से सीधे या अप्रत्यक्ष रूप से निपटती है, को IDisposable इंटरफेस को लागू करना चाहिए और IDisposable इंटरफेस के अंदर घोषित Dispose मेथड को लागू करना चाहिए। हम सीधे अनमैनेज्ड ऑब्जेक्ट्स से नहीं निपटते। लेकिन हम मैनेज्ड क्लासेस से निपटते हैं, जो सीधे अनमैनेज्ड ऑब्जेक्ट्स से निपटते हैं। उदाहरण: फाइल हैंडलर्स, कनेक्शन स्ट्रिंग्स, HTTP स्ट्रीम्स, आदि।

इस पैटर्न का एक महत्वपूर्ण पहलू यह है कि यह विरासत में मिली क्लासेस के लिए IDisposable डिज़ाइन पैटर्न का पालन करना आसान बनाता है। और यह एक ओवरराइडेबल Dispose मेथड के कार्यान्वयन के कारण है। यह पैटर्न फाइनलाइज़र मेथड (या C# में डिस्ट्रक्टर) के उपयोग का भी सुझाव देता है। हालांकि, यदि हम फाइनलाइज़र का उपयोग करते हैं, तो इसके प्रदर्शन निहितार्थों के कारण इसे ठीक से प्रबंधित किया जाना चाहिए।

पूर्ण IDisposable पैटर्न कार्यान्वयन

using System;
using System.Net.Http;

public class ServiceProxy : IDisposable
{
    private readonly HttpClient _httpClient;
    private bool _disposed = false;

    public ServiceProxy(IHttpClientFactory httpClientFactory)
    {
        _httpClient = httpClientFactory.CreateClient();
    }

    // फाइनलाइज़र (डिस्ट्रक्टर) - केवल अनमैनेज्ड संसाधन होने पर आवश्यक
    ~ServiceProxy()
    {
        Dispose(false);
    }

    // पब्लिक Dispose मेथड
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this); // फाइनलाइज़र को कॉल होने से रोकता है
    }

    // प्रोटेक्टेड वर्चुअल Dispose - विरासत के लिए अनुमति देता है
    protected virtual void Dispose(bool disposing)
    {
        if (_disposed) return;

        if (disposing)
        {
            // मैनेज्ड संसाधन डिस्पोज़ करें
            _httpClient?.Dispose();
        }

        // अनमैनेज्ड संसाधन यहां डिस्पोज़ करें (यदि कोई हो)
        // उदाहरण: Marshal.FreeHGlobal(unmanagedPtr);

        _disposed = true;
    }

    public async Task<HttpResponseMessage> GetAsync(string url)
    {
        return await _httpClient.GetAsync(url);
    }

    public async Task<HttpResponseMessage> PostAsync(string url, StringContent content)
    {
        return await _httpClient.PostAsync(url, content);
    }
}

उपयोग: using स्टेटमेंट के साथ

static async Task Main(string[] args)
{
    using var serviceProxy = new ServiceProxy(httpClientFactory);
    
    var response = await serviceProxy.GetAsync("https://api.example.com/data");
    var content = await response.Content.ReadAsStringAsync();
    Console.WriteLine(content);
    
    // स्वचालित रूप से Dispose() कॉल होता है यहां
}

पैटर्न के मुख्य घटक

घटकउद्देश्य
IDisposable इंटरफेसकॉन्ट्रैक्ट परिभाषित करता है
Dispose() (पब्लिक)निर्धारक सफाई, GC.SuppressFinalize कॉल करता है
Dispose(bool) (प्रोटेक्टेड वर्चुअल)वास्तविक सफाई तर्क, विरासत की अनुमति देता है
~Finalizer()सुरक्षा जाल यदि Dispose नहीं कॉल किया गया
_disposed फ्लैगडबल-डिस्पोज़ रोकता है

विरासत में मिली क्लास के लिए पैटर्न

public class DerivedService : ServiceProxy
{
    private readonly MemoryStream _stream = new MemoryStream();
    private bool _disposed = false;

    protected override void Dispose(bool disposing)
    {
        if (_disposed) return;

        if (disposing)
        {
            _stream?.Dispose(); // अपने मैनेज्ड संसाधन डिस्पोज़ करें
        }

        // अपने अनमैनेज्ड संसाधन डिस्पोज़ करें

        _disposed = true;
        base.Dispose(disposing); // बेस Dispose कॉल करें!
    }
}

सर्वोत्तम अभ्यास

  • हमेशा using स्टेटमेंट या await using (IAsyncDisposable के लिए) का उपयोग करें
  • यदि कोई अनमैनेज्ड संसाधन नहीं है तो फाइनलाइज़र न लिखें
  • Dispose(bool) को protected virtual बनाएं विरासत के लिए
  • GC.SuppressFinalize(this) कॉल करें जब मैन्युअली डिस्पोज़ कर रहे हों
  • _disposed फ्लैग के साथ आइडेम्पोटेंट बनाएं

.NET Core 3.0+: IAsyncDisposable

public class AsyncService : IAsyncDisposable
{
    private readonly HttpClient _client = new HttpClient();

    public async ValueTask DisposeAsync()
    {
        await _client.DisposeAsync();
    }
}

// उपयोग
await using var service = new AsyncService();
  1. Android Pull-to-Refresh कैसे लागू करें? Android Pull-to-Refresh कैसे लागू करें?

    Android Pull-to-Refresh (Swipe-to-Refresh) लागू करना उदाहरण में जाने से पहले, हमें पता होना चाहिए कि Android में Pull to Refresh लेआउट क्या है। हम Android में Pull to Refresh को Swipe-to-Refresh कह सकते हैं। जब आप स्क्रीन को ऊपर से नीचे की ओर स्वाइप करते हैं तो यह setOnRefreshListener के आधार पर कुछ

  1. C++ में कम्पोजिट डिज़ाइन पैटर्न C++ में कम्पोजिट डिज़ाइन पैटर्न

    कम्पोजिट पैटर्न का उपयोग वहां किया जाता है जहां हमें ऑब्जेक्ट्स के एक समूह को एक सिंगल ऑब्जेक्ट के समान तरीके से ट्रीट करने की आवश्यकता होती है। कम्पोजिट पैटर्न ऑब्जेक्ट्स को ट्री स्ट्रक्चर के रूप में कंपोज करता है ताकि पार्ट और होल हायरार्की दोनों को दर्शाया जा सके। इस प्रकार का डिज़ाइन पैटर्न स्ट्

  1. पायथन में पैटर्न कैसे प्रिंट करें पायथन में पैटर्न कैसे प्रिंट करें

    पायथन में पैटर्न्स को नेस्टेड फॉर लूप्स का उपयोग करके प्रिंट किया जा सकता है। बाहरी लूप का उपयोग पंक्तियों की संख्या के माध्यम से इटरेट करने के लिए किया जाता है जबकि आंतरिक लूप का उपयोग स्तंभों की संख्या को संभालने के लिए किया जाता है। प्रिंट स्टेटमेंट को आवश्यकतानुसार विभिन्न पैटर्न बनाने के लिए मॉ