سؤال

تخيل الفئة الأساسية مع العديد من المنشئات الظاهري طريقة

public class Foo
{
   ...
   public Foo() {...}
   public Foo(int i) {...}
   ...
   public virtual void SomethingElse() {...}
   ...
}

والآن أريد إنشاء سليل الفئة التي يتجاوز أسلوب الظاهري:

public class Bar : Foo 
{
   public override void SomethingElse() {...}
}

و آخر سليل أن يفعل بعض الأشياء:

public class Bah : Bar
{
   public void DoMoreStuff() {...}
}

هل يجب نسخ جميع المنشئات من فو في شريط باه ؟ ثم إذا قمت بتغيير منشئ التوقيع في فو ، هل يجب علي تحديث في شريط باه ؟

هل هناك أي طريقة أن يرث البنائون ؟ هل هناك أي وسيلة لتشجيع إعادة استخدام التعليمات البرمجية?

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

المحلول

نعم ، سيكون لديك لتنفيذ منشئات أن معنى لكل الاشتقاق ومن ثم استخدام base الكلمة المباشرة التي منشئ المناسبة قاعدة الطبقة أو this الكلمات الرئيسية لتوجيه منشئ آخر منشئ في نفس الفئة.

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

التحديث

في C#4 يمكنك تحديد قيم المعلمات الافتراضية واستخدام اسمه المعلمات لجعل واحدة منشئ دعم متعددة حجة تكوينات بدلا من وجود منشئ واحد في التكوين.

نصائح أخرى

387 منشئات??هذا هو المشكلة الرئيسية الخاصة بك.ماذا عن هذا بدلا من ذلك ؟

public Foo(params int[] list) {...}

نعم ، يجب عليك نسخ كل 387 المنشئات.يمكنك القيام ببعض الاستخدام عن طريق إعادة توجيه لهم:

  public Bar(int i): base(i) {}
  public Bar(int i, int j) : base(i, j) {}

ولكن هذا أفضل ما يمكنك القيام به.

للأسف نحن نوعا ما على أن تخبر المترجم واضح:

Subclass(): base() {}
Subclass(int x): base(x) {}
Subclass(int x,y): base(x,y) {}

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

لا تنسى أنه يمكنك أيضا إعادة توجيه منشئات أخرى المنشئات في نفس المستوى من الميراث:

public Bar(int i, int j) : this(i) { ... }
                            ^^^^^

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

public class FooParams
{
    public int Size...
    protected myCustomStruct _ReasonForLife ...
}
public class Foo
{
    private FooParams _myParams;
    public Foo(FooParams myParams)
    {
          _myParams = myParams;
    }
}

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

public class Bar : Foo
{
    public Bar(FooParams myParams) : base(myParams) {}
}

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

كما Foo هي فئة يمكنك إنشاء الظاهري زائد Initialise() الأساليب ؟ ثم أنها سوف تكون متاحة إلى فئات فرعية و لا يزال الموسعة?

public class Foo
{
   ...
   public Foo() {...}

   public virtual void Initialise(int i) {...}
   public virtual void Initialise(int i, int i) {...}
   public virtual void Initialise(int i, int i, int i) {...}
   ... 
   public virtual void Initialise(int i, int i, ..., int i) {...}

   ...

   public virtual void SomethingElse() {...}
   ...
}

هذا لا ينبغي أن يكون أداء أعلى تكلفة ما لم يكن لديك الكثير من الخاصية الافتراضية القيم و تضغط عليه كثيرا.

public class BaseClass
{
    public BaseClass(params int[] parameters)
    {

    }   
}

public class ChildClass : BaseClass
{
    public ChildClass(params int[] parameters)
        : base(parameters)
    {

    }
}

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

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

خذ على سبيل المثال إذا كنت تريد تجاوز النظام.IO.فئة StreamWriter, تحتاج إلى إضافة كل 7 منشئات إلى فئة جديدة ، و إذا كنت تحب وتعليقا تحتاج إلى تعليق كل واحد مع رأس XML.لجعل الأمور أسوأ ، الفوقية عرض dosnt وضع XML التعليقات المناسبة XML التعليقات ، لذلك علينا أن نذهب خط خط نسخ ولصق لهم.ما كان Microsoft التفكير هنا ؟

أنا فعلا كتبت أداة صغيرة حيث يمكنك لصق في البيانات الوصفية الرمز وسيتم تحويله إلى XML التعليقات باستخدام overidden الرؤية.

هل يجب نسخ جميع المنشئات من Foo في Bar و Bah?ثم إذا قمت بتغيير منشئ التوقيع في Foo, هل يجب تحديث كان في Bar و Bah?

نعم ، إذا كنت تستخدم منشئات لخلق الحالات.

هل هناك أي طريقة أن يرث البنائون ؟

لا.

هل هناك أي وسيلة لتشجيع إعادة استخدام التعليمات البرمجية?

لن ندخل في ما إذا كان وراثة منشئات سيكون جيدا أو سيئا إذا كان تشجيع إعادة استخدام التعليمات البرمجية, بما أننا لا نملك لهم و نحن لن تحصل عليها.:-)

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

يبدو مثل هذا:

// In Foo:
public T create<T>(int i) where: where T : Foo, new() {
    T obj = new T();
    // Do whatever you would do with `i` in `Foo(i)` here, for instance,
    // if you save it as a data member;  `obj.dataMember = i;`
    return obj;
}

أن تقول أنه يمكنك دعوة عامة create وظيفة باستخدام نوع المعلمة وهو أي نوع فرعي من Foo أن لديه صفر-الحجج منشئ.

ثم بدلا من ان تقوم Bar b new Bar(42), تفعل هذا:

var b = Foo.create<Bar>(42);
// or
Bar b = Foo.create<Bar>(42);
// or
var b = Bar.create<Bar>(42); // But you still need the <Bar> bit
// or
Bar b = Bar.create<Bar>(42);

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

فقط للتوضيح:اسم create ليس مهما ، يمكن أن يكون makeThingy أو أي شيء آخر تريد.

كامل سبيل المثال

using System.IO;
using System;

class Program
{
    static void Main()
    {
        Bar b1 = Foo.create<Bar>(42);
        b1.ShowDataMember("b1");

        Bar b2 = Bar.create<Bar>(43); // Just to show `Foo.create` vs. `Bar.create` doesn't matter
        b2.ShowDataMember("b2");
    }

    class Foo
    {
        public int DataMember { get; private set; }

        public static T create<T>(int i) where T: Foo, new()
        {
            T obj = new T();
            obj.DataMember = i;
            return obj;
        }
    }

    class Bar : Foo
    {
        public void ShowDataMember(string prefix)
        {
            Console.WriteLine(prefix + ".DataMember = " + this.DataMember);
        }
    }
}

المشكلة ليست تلك الحانة و باه يكون نسخة 387 الصانعين ، المشكلة هي أن فو قد 387 المنشئات.فو بوضوح يفعل أشياء كثيرة جدا - ريفاكتور سريعة!أيضا, إلا إذا كان لديك سبب وجيه حقا أن يكون القيم في منشئ (إذا توفر parameterless منشئ, ربما كنت لا) ، أنصح باستخدام خاصية الحصول على/الإعداد.

لا, أنت لا تحتاج إلى نسخ جميع 387 المنشئات شريط باه.شريط باه يمكن أن يكون كثير أو قليل من منشئات كما تريد مستقلة من كم تعرف على Foo.على سبيل المثال يمكنك أن تختار أن يكون مجرد شريط واحد منشئ الذي يبني فو مع فوو 212 منشئ.

نعم, أي منشئات تغيير في فو الذي شريط أو باه تعتمد على تتطلب منك تعديل شريط باه وفقا لذلك.

لا توجد طريقة في .صافي وراثة المنشئات.ولكن يمكنك تحقيق إعادة استخدام التعليمات البرمجية عن طريق استدعاء منشئ الفئة الأساسية داخل فرعية منشئ أو عن طريق الاتصال الظاهري طريقة تعريف (مثل تهيئة()).

كنت قد تكون قادرة على التكيف مع نسخة من C++ الظاهري منشئ لغة.بقدر ما أعرف, C# لا يدعم أنواع الإرجاع طردي.وأعتقد أن في كثير من الشعوب قوائم ترغب.

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

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