سؤال

لدي 100 فئة لها بعض العناصر المماثلة وبعضها فريد من نوعها. لقد قمت بإنشاء واجهة تسمي تلك العناصر المماثلة على سبيل المثال: واجهة Ianimal. ما أود فعله عادة هو:

class dog : IAnimal

ولكن هناك 100 فئة ولا أشعر بالرغبة في الذهاب لهم جميعًا والبحث عن تلك التي يمكنني تطبيقها.

ما أريد فعله هو:

dog scruffy = new dog();
cat ruffles = new cat();

IAnimal[] animals = new IAnimal[] {scruffy as IAnimal, ruffles as IAnimal} // gives null

أو

IAnimal[] animals = new IAnimal[] {(IAnimal)scruffy, (IAnimal)ruffles} //throws exception

ثم افعل

foreach (IAnimal animal in animals)
{
   animal.eat();
}

هل هناك طريقة لجعل C# اسمحوا لي أن أعامل الكشكشة والكثبّة كإيانيم دون الاضطرار إلى الكتابة: Ianimal عند كتابة الفصل.

شكرًا!

تحرير (ليس كسولًا): يتم إنشاء الفصول من SQL SQL Metadata ، مما يعني في كل مرة يتم إنشاؤها ، سأضطر إلى العودة وإضافتها ، أو تعديل مولد الرمز لتحديد الأعضاء الموجودين في الواجهة ، في الواقع هذه ليست فكرة سيئة. كنت آمل أن يكون هناك نوع من نهج الأدوية أو شيء من هذا القبيل.

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

المحلول

يمكنك حل هذه المشكلة مع فصول جزئية: اسمح للرمز المولد/المجدد في ملف مصدر واحد لكل فئة ، والجزء المرفق يدويًا (تحديد الفئة الفرعية من Ianimal) في أخرى.

نصائح أخرى

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

سيكون مشروعًا مثيرًا للاهتمام لمحاولة.

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

يمكنك إنشاء محول يصل "eat"من خلال التفكير ، كتابة البط الفقير:

public class Adapter<T> : IAnimal
{
   private T x;

   Adapter(T x)
   {
     this.x = x;
   }

   public void eat()
   {
     x.GetType().GetMethod("eat").Invoke(this);
   }
}

ثم يمكنك استخدامه مثل هذا:

dog scruffy = new dog();
cat ruffles = new cat();

IAnimal[] animals = new IAnimal[] {new Adapter<dog>(scruffy), new Adapter<cat>(ruffles )};

ليس من السهل أن أدرك ، يمكنك إجراء مكالمة ملزمة متأخرة باستخدام التفكير ولكن من الأفضل أن تقضي وقتك في تحرير الفصول الدراسية أو كتابة ماكرو للقيام بذلك.

على افتراض أنك لا تستطيع تعديل فئة القط لأسباب وجيهة ،

يمكنك كتابة محول للقط الموروثة من Ianimal IE:

  class cat_adapter : IAnimal
  {
       private cat baseCat;
       public cat_adapter( cat aCat)
       {
           baseCat = aCat;
       }

       // Implement IAnimal interface and redirect to baseCat
       public void eat()
       {
            baseCat.munchOnMeowMix();
       }

  }

في C ++ ، يمكنك استخدام قوالب على افتراض أن جميع الفصول التي تم إنشاؤها تحتاج إلى الحصول على نفس الوظيفة المسمى:

  template <class BaseType>
  class CAnimalAdapter : public IAnimal
  {
  private:
        BaseType* m_baseInstance;
  public:
        CAnimalAdapter(BaseType* baseInstance) :
            m_baseInstance(baseInstance)
        {
        }

        void eat()
        {
            // You will get a compiler error if BaseType doesn't have this implemented
            baseInstance->doEat();                
        }

  }

ربما يمكن لشخص أكثر من C#-py أن يفعل الشيء نفسه مع التفكير.

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

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

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

إذا كنت قد قمت بالفعل بتطبيق هذه الطريقة وترغب فقط في تطبيق الواجهة ، فيمكنك استخدام تعبير منتظم مع أمر استبدال في الملفات في IDE.

خلاف ذلك ، ألقِ نظرة على طرق التمديد. قد تناسب حاجتك.

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

هذا النوع من النهج هو كيف سيقوم LINQ TO SQL بإنشاء ملفات فئة.

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