لماذا يمكن أن ترث فئة AC# من واجهة واحدة ضمنيًا وصراحة؟

StackOverflow https://stackoverflow.com/questions/253058

سؤال

صادف اليوم أن أجد أن فئة C# واحدة يمكن أن ترث واجهة واحدة بطريقة ضمنية وصريحة. هذا يفاجئني. إذا كان C# يعمل بهذه الطريقة ، فيمكن أن يتصرف مثيل واحد بشكل مختلف عند الإشارة إليه بطريقة مختلفة.

interface IFoo
{
    void DoSomething();
}

class Foo : IFoo
{
    #region IFoo Members
    public void DoSomething()
    {
        Console.WriteLine("do something implicitly");
    }
    #endregion

    #region IFoo Members
    void IFoo.DoSomething()
    {
        Console.WriteLine("do something explicitly");
    }
    #endregion
}


        Foo f = new Foo();
        f.DoSomething();

        ((IFoo)f).DoSomething();

تشغيل الرمز أعلاه والإخراج

do something implicitly
do something explicitly

أعتقد أن هذا التصميم من C# يجعل عدم الاتساق من السلوك. ربما يكون من الضروري أن يرث فئة C# واحدة من واجهة واحدة بطريقة ضمنية أو شرح ، ولكن ليس كلاهما.

هل هناك أي سبب من سبب تصميم C# بهذه الطريقة؟

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

المحلول

مثالك يفعل ليس تنفيذ IFOO ضمنيًا وصريحًا. يمكنك فقط تنفيذ ifoo.dosometing () بشكل صريح. لديك طريقة جديدة في صفك تسمى dosomething (). لا علاقة له بـ ifoo.dosomething ، إلا أنه يحتوي على نفس الاسم والمعلمات.

نصائح أخرى

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

عندما يكون لدى الفصل نفس اسم العضو والأنواع المرتبطة به كواجهة لكن كما أنه ينفذ بشكل صريح العضو المقابل للواجهة ، ثم التنفيذ "الضمني" للفئة ليس يعتبر تنفيذ الواجهة على الاطلاق (ما لم يطلق عليه التنفيذ الصريح).

بالإضافة إلى معاني مختلفة في كل حالة حيث تنفذ الفصل واجهات متعددة مع نفس اسم/أنواع العضو ، حتى مع وجود واجهة واحدة فقط ، الطبقة نفسها يعتبر أن لديها واجهة ضمنية قد تحتوي على نفس الأعضاء/أنواع الواجهة الوحيدة ولكن لا تزال تعني شيئًا مختلفًا.

هذا يجعلها أكثر مرونة عندما تكون هناك تصادمات. على وجه الخصوص ، انظر إلى IEnumerator و IEnumerator<T> - كلاهما لديه Current خاصية ، ولكن من أنواع مختلفة. أنت لديك لاستخدام تنفيذ الواجهة الصريحة من أجل تنفيذ كل من (والنموذج العام يمتد النموذج غير العام).

الميراث المتعدد: ماذا لو كنت تستمد من واجهتين تحدد نفس الطريقة لأغراض مختلفة؟

  interface IMoveable
  {
    public void Act();
  }

  interface IRollable
  {
    public void Act();
  }

  class Thing : IMoveable, IRollable
  {
    //TODO Roll/Move code here

    void IRollable.Act()
    {
      Roll();
    }

    void IMoveable.Act()
    {
      Move();
    }
  }

يا رفاق ، شكرا على إجاباتك.

اتضح أن "C# Class يمكن أن يرث واجهة واحدة بطريقة ضمنية وصريحة في نفس الوقت" هو في الواقع وهم. في الواقع ، يمكن لفئة واحدة أن ترث واجهة واحدة لمرة واحدة.

في السؤال الأصلي ، تبدو طريقة "dosomething" "واجهة" IFOO ضمنيًا (يتم إنشاء الطريقة بالفعل بواسطة VS2008) ، لكنها في الواقع ليست كذلك. مع التنفيذ الصريح للواجهة IFOO ، تتحول طريقة "dosomething" إلى طريقة طبيعية لا علاقة لها بـ IFOO إلا بنفس التوقيع.

ما زلت أعتقد أنه تصميم صعب لـ C#، ومن السهل استخدامه عن طريق الخطأ. قل ، لدي بعض الكود مثل هذا

        Foo f = new Foo();
        f.DoSomething();

الآن ، أريد إعادة تشكيله إلى الكود أدناه. يبدو الأمر جيدًا تمامًا ، لكن نتيجة التنفيذ مختلفة.

        Action<IFoo> func = foo => foo.DoSomething();
        func(f);
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top