سؤال

في Visual Studio، عندما أكتب السطر "Implements IDisposable"، يضيف IDE تلقائيًا:

  • أ disposedValue متغير العضو
  • أ Sub Dispose() Implements IDisposable.Dispose
  • أ Sub Dispose(ByVal disposing As Boolean)

ال Dispose() يجب تركه بمفرده، ويجب إدخال رمز التنظيف Dispose(disposing).

ومع ذلك التخلص من النمط النهائي يقول يجب عليك تجاوز أيضا Sub Finalize() للإتصال Dispose(False).لماذا لا يضيف IDE هذا أيضًا؟هل يجب أن أضيفه بنفسي أم أنه يسمى ضمنيًا بطريقة ما؟

يحرر: هل لديك أي فكرة عن سبب قيام IDE بإضافة 80% من العناصر المطلوبة تلقائيًا ولكنه يترك طريقة الإنهاء؟أليس المغزى من هذا النوع من الميزات هو مساعدتك لا ننسى هذه الأشياء؟

تحرير 2: شكرًا لكم جميعًا على إجاباتكم الممتازة، وهذا أصبح الآن منطقيًا تمامًا!

هل كانت مفيدة؟

المحلول

إذا كنت تمتلك بالفعل موارد غير مُدارة والتي لن يتم تنظيفها تلقائيًا بواسطة أداة تجميع البيانات المهملة وتنظيفها في Dispose()، فنعم، يجب عليك أن تفعل الشيء نفسه في Finalize().

إذا كنت تقوم بتنفيذ IDisposable لسبب آخر، فلن يكون تنفيذ Finalize() مطلوبًا.

السؤال الأساسي هو هذا:إذا لم يتم استدعاء Dispose() وتم جمع البيانات المهملة لكائنك، فهل ستتسرب الذاكرة؟إذا كانت الإجابة بنعم، قم بتنفيذ Finalize.إذا كان الجواب لا، لا تحتاج إلى ذلك.وتجنب أيضًا تنفيذ Finalize "لمجرد أنه أكثر أمانًا".من المحتمل أن تحتاج الكائنات ذات أدوات الإنهاء المخصصة إلى مرورين من GC لتحريرها - مرة واحدة لوضعها في قائمة انتظار أدوات الإنهاء المعلقة، وتمريرة ثانية لتحرير ذاكرتها فعليًا.

نصائح أخرى

لا، لا تحتاج إلى الإنهاء إلا إذا كانت لديك موارد غير مُدارة للتنظيف.

في معظم الحالات، يكون السبب وراء إمكانية التخلص من الفئة هو أنها تحتفظ بمراجع إلى كائنات IDisposable مُدارة أخرى.في هذه الحالة، لا توجد طريقة نهائية ضرورية أو مرغوبة.

Implements IDisposable

Public Overloads Sub Dispose() Implements IDisposable.Dispose

    Dispose(True)
    GC.SuppressFinalize(Me)

End Sub

Protected Overloads Sub Dispose(ByVal disposing As Boolean)

    If disposing Then
        ' Free other state (managed objects).
    End If
    ' Free your own state (unmanaged objects).
    ' Set large fields to null.
End Sub

Protected Overrides Sub Finalize()

    Dispose(False)
    MyBase.Finalize()

End Sub

كما قال الآخرون، لا تحتاج إلى تنفيذ أداة الإنهاء إلا إذا كنت تحتفظ مباشرةً بموارد غير مُدارة.أيضًا، بافتراض أنك تعمل في .NET 2.0 أو إصدار أحدث، فمن غير المحتمل أن تحتاج إلى تنفيذ أداة نهائية لأنه يمكن استخدام SafeHandle عادةً لتغليف مواردك غير المُدارة.

كتبت أ مشاركة مدونة طويلة إلى حد ما تغطية الخلفية وتنفيذ IDisposable و Finalizers منذ فترة، والتي قد تستحق القراءة إذا لم تكن واضحًا تمامًا بشأنها.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top