سؤال

نظرا التالية الميراث شجرة, ما يمكن أن يكون أفضل طريقة لتنفيذ ذلك في الطريقة التي يعمل ؟

abstract class Foo<T> : IEnumerable<T>
{
    public abstract Bar CreateBar();
}

class Bar<T> : Foo<T>
{
    // Bar's provide a proxy interface to Foo's and limit access nicely.
    // The general public shouldn't be making these though, they have access
    // via CreateBar()
    protected Bar(Foo base)
    {
        // snip...
    }
}

class Baz<T> : Foo<T>
{
    public Bar CreateBar()
    {
        return new Bar(this);
    }
}

فشل هذا مع: 'Bar.Bar()' is inaccessible due to its protection level.

أنا لا أريد منشئ العامة فقط الفئات التي ترث من Foo يجب أن تكون قادرة على خلق Bars. Bar هو متخصص Foo, و أي نوع من Foo يجب أن تكون قادرة على خلق واحد.الداخلية العامة هو "الخيار" هنا ، كما أن الغالبية العظمى من ملحقات محددة مسبقا إلى Foo سيتم الداخلية إلى DLL ، ولكن أنا أعتبر هذا قذرة الإجابة, أن أي شخص يأتي جنبا إلى جنب في وقت لاحق من يريد خلق نوع الخاصة بهم من Foo أو Baz (والتي من المرجح أن يحدث) سوف يكون عالقا مع الافتراضي CreateBar() التنفيذ التي قد أو قد لا تلبي احتياجاتهم.

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

تحرير (مزيد من المعلومات):

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

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

المحلول

حسنا إجابة جديدة:

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

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

نصائح أخرى

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

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

يمكنك الوصول إلى شريط منشئ خلال متداخلة نوع داخل فو:

abstract class Foo<T> : IEnumerable<T>
{
  public abstract Bar<T> CreateBar();

  protected Bar<T> CreateBar(Foo<T> f) { return new FooBar(f); }

  private class FooBar : Bar<T> 
   { public FooBar(Foo<T> f) : base(f) {}   
   }
}

class Bar<T> : Foo<T>
{ protected Bar(Foo<T> @base) {}
}

class Baz<T> : Foo<T>
{
    public override Bar<T> CreateBar() 
    {
        return CreateBar(this);
    }
}

ننسى للحظة أن شريط مستمد من فو.إذا كنت تفعل هذا ، يبدو أن المشكلة هي "كيف تجعل من ذلك أن كل فئة فرعية من فو يمكن إنشاء شريط, حتى لو كان فرعية لا يكون الوصول إلى شريط منشئ؟"

هذه مشكلة سهلة جدا لحل:

public class Foo
{
   protected static Bar CreateBarInstance()
   {
      return new Bar();
   }
   public virtual Bar CreateBar()
   {
      return CreateBarInstance();
   }
}

public class Bar
{
    internal Bar()
    {
    }
}

public class Baz : Foo
{
    public override Bar CreateBar()
    {
        Bar b = base.CreateBar();
        // manipulate the Bar in some fashion
        return b;
    }
}

إذا كنت ترغب في ضمان أن الفئات الفرعية من فو لم يكن لديك الوصول إلى شريط منشئ ، ووضعها في الجمعية.

الآن لاستخلاص شريط من فو ، إنه تغيير بسيط:

public class Bar : Foo
{
    internal Bar()
    {
    }
    public override Bar CreateBar()
    {
        throw new InvalidOperationException("I'm sorry, Dave, I can't do that.");
    }

}

"أنا لا أريد منشئ العامة." التحقق.

"فقط الفئات التي ترث من فو يجب أن تكون قادرة على خلق القضبان." التحقق.

"أي نوع من فو يجب أن تكون قادرة على خلق واحد." تحقق ،

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

C# لا توفر المباشر ما يعادل C++ صديق الكلمة.يبدو التصميم الخاص بك يتطلب هذا النوع من بناء.

في C++ هل يمكن أن تعين فئة معينة من الوصول إلى القطاع الخاص/حماية أعضاء فئة أخرى باستخدام "صديق".ملاحظة:هذا ليس هو نفسه C# الداخلية التعديل الذي يتيح الوصول إلى جميع الطبقات داخل نفس الجمعية.

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

هذا منتدى آخر ويوضح كذلك ويظهر بعض الأمثلة على كيفية القيام بذلك.

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