سؤال

كنت مؤخرا قد نفذت الطبقة مثل:

class TestClass : IDisposable
{
    RegistryKey m_key;
    public TestClass()
    {
        m_key = Registry.CurrentUser.OpenSubKey("Software", false);
    }

    public void Dispose()
    {
        // m_key.Dispose();
        IDisposable disp = m_key;
        disp.Dispose();
    }
}

لو ضافه دعوة مباشرة للتخلص لي خطأ CS0117 ("'Microsoft.Win32.RegistryKey' لا تحتوي على تعريف 'التصرف'").بعض غوغلينغ قادني إلى هذا الموضوع, حيث تعلمت ما كان يحدث ، لذلك أنا الآن فهم الميكانيكا من ذلك.على MSDN الوثائق تشير إلى أن الكاتب يفضل أن أسميه Close() بدلا من التصرف () ، ولكن هذا لا يفسر لماذا.

ما هو الغرض من هذا النمط (الذي أعتقد أنني قد رأيت ذلك في IO الطبقات وكذلك)?في ضوء حقيقة أن هذا كان مقصود قرار من قبل الطبقة المؤلف كيف السيئة هي رمز أعلاه (دعوة للتخلص من خلال واجهة IDisposable)?لا يمكن أن يكون سيئا للغاية بعد كل شيء ، هذا ما سيحدث في استخدام البيان ، أليس كذلك ؟

[التعديلات:1) تغيير العنوان من "غير عامة" إلى "الصريحة" 2) إزالة صريحة التنفيذ من قانون بلدي ، تركت بطريق الخطأ في من التجريب]

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

المحلول

وهذا ما يسمى صريحة واجهة التنفيذ.في المثال الخاص بك حيث يمكنك تحديد طريقة Dispose() بأنها "باطلة IDisposable.Dispose()" أنت صراحة تنفيذ واجهة IDisposable كذلك.

ويتم هذا عادة لتجنب الاصطدامات.إذا كان Microsoft في أي وقت أراد أن إضافة آخر Dispose() الطريقة التي فعلت شيئا آخر RegistryKey أنها لن تكون قادرة على ما لم تستخدم صريحة تنفيذ تلك الواجهة.

ويتم ذلك في كثير من الأحيان مع عامة IEnumerable<T> واجهة.فإنه يتطلب منك أيضا تنفيذ غير عامة واجهة IEnumerable.فقط الأعضاء في هذين واجهات هو GetEnumerator مع عام واحد يجري أكثر فائدة ، لذلك عادة ما تنفذ مثل هذا:

public clas SomeClass : IEnumerable<SomeOtherClass>
{
    public IEnumerator<SomeOtherClass> GetEnumerator ()
    {
        ...
    }

    IEnumerator IEnumerable.GetEnumerator ()
    {
        return GetEnumerator ();
    }
}

هذه الطريقة عند استدعاء كائن من SomeClass هو GetEnumator الأسلوب ، ويدعو عام الإصدار منذ الأخرى التي نفذت بها صراحة ، مما يتيح لنا الحصول على القوي-كتابة الأدوية تسمح.

انظر الصفحات من 166-169 البرمجة C# بواسطة جيسي الحرية (أنا عندي الطبعة الرابعة).

نصائح أخرى

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

هذا هو مؤلم إذا كان لديك إشارة إلى موضوع ترغب في استدعاء واجهة الطريقة (كما في المثال أعلاه) ، ولكن أنا التخفيف من حدة ذلك عن طريق كتابة:

class C : IDisposable
{
    public IDisposable IDisposable { get { return this; } }
    void IDisposable.Dispose() { }
}

وهو ما يعني أن استدعاء الأسلوب على C تبدو مثل:

C c = ...
c.IDisposable.Dispose();

مترجم يوزع هذا "استدعاء IDisposable مكان الإقامة على C ثم اتصل Dispose() الطريقة على النتيجة" لكن قرأت أنها "دعوة IDisposable.Dispose() طريقة C"والذي يبدو من الطبيعي هنا.

هذا النهج يمكن الحصول على القبيح عند استخدام واجهات عامة ، لسوء الحظ.

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