constructor شرح - استدعاء مُنشئ القاعدة في C#




java (9)

إذا كنت ترث من فئة أساسية وترغب في تمرير شيء من مُنشئ الفصل الموروث إلى مُنشئ الفصل الأساسي ، كيف أفعل ذلك؟

فمثلا،

إذا كنت أرث من فئة الاستثناء ، فأنا أريد أن أفعل شيئًا كالتالي:

class MyExceptionClass : Exception
{
     public MyExceptionClass(string message, string extraInfo)
     {
         //This is where it's all falling apart
         base(message);
     }
}

أساسا ما أريده هو أن تكون قادرة على تمرير رسالة السلسلة إلى فئة استثناء قاعدة.


Answers

يمكنك أيضًا إجراء فحص مشروط وتمرير في الخصائص في المُنشئ ، مما يتيح بعض المرونة.

public MyClass(object myObject=null): base(myObject ?? new myOtherObject())
{
}

أو

public MyClass(object myObject=null): base(myObject==null ? new myOtherObject(): myObject)
{
}

صحيح أن استخدام base (شيء) لاستدعاء منشئ الطبقة الأساسية ، ولكن في حالة الحمولة الزائدة استخدام this الكلمة

public ClassName() : this(par1,par2)
{
// do not call the constructor it is called in the this.
// the base key- word is used to call a inherited constructor   
} 

// Hint used overload as often as needed do not write the same code 2 or more times

public class MyException : Exception
{
    public MyException() { }
    public MyException(string msg) : base(msg) { }
    public MyException(string msg, Exception inner) : base(msg, inner) { }
}

public class MyExceptionClass : Exception
{
    public MyExceptionClass(string message,
      Exception innerException): base(message, innerException)
    {
        //other stuff here
    }
}

يمكنك تمرير استثناء داخلي إلى أحد الصانعين.


تعديل المُنشئ الخاص بك إلى التالي بحيث يستدعي منشئ الفئة الأساسية بشكل صحيح:

public class MyExceptionClass : Exception
{
    public MyExceptionClass(string message, string extrainfo) : base(message)
    {
        //other stuff here
    }
}

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


لاحظ أنه يمكنك استخدام أساليب ثابتة داخل استدعاء مُنشئ القاعدة.

class MyExceptionClass : Exception
{
     public MyExceptionClass(string message, string extraInfo) : 
         base(ModifyMessage(message, extraInfo))
     {
     }

     private static string ModifyMessage(string message, string extraInfo)
     {
         Trace.WriteLine("message was " + message);
         return message.ToLowerInvariant() + Environment.NewLine + extraInfo;
     }
}

من المبادئ التوجيهية لتصميم الإطار وقواعد FxCop. :

1. يجب أن يكون للإستثناء المخصص اسم ينتهي بـ "استثناء"

    class MyException : Exception

2. يجب أن يكون الاستثناء العام

    public class MyException : Exception

3. CA1032: يجب أن يقوم استثناء بتنفيذ الصانعين القياسيين.

  • مُنشئ عام بلا معلمات.
  • مُنشئ عام بوسيطة سلسلة واحدة.
  • مُنشئ عام بسلسلة واحدة واستثناء (كما يمكن أن يؤدي إلى التفاف استثناء آخر).
  • يكون منشئ التسلسل محميًا إذا لم يكن النوع مغلقًا وخاصًا إذا كان النوع مغلقًا. على أساس MSDN :

    [Serializable()]
    public class MyException : Exception
    {
      public MyException()
      {
         // Add any type-specific logic, and supply the default message.
      }
    
      public MyException(string message): base(message) 
      {
         // Add any type-specific logic.
      }
      public MyException(string message, Exception innerException): 
         base (message, innerException)
      {
         // Add any type-specific logic for inner exceptions.
      }
      protected MyException(SerializationInfo info, 
         StreamingContext context) : base(info, context)
      {
         // Implement type-specific serialization constructor logic.
      }
    }  
    

أو

    [Serializable()]
    public sealed class MyException : Exception
    {
      public MyException()
      {
         // Add any type-specific logic, and supply the default message.
      }

      public MyException(string message): base(message) 
      {
         // Add any type-specific logic.
      }
      public MyException(string message, Exception innerException): 
         base (message, innerException)
      {
         // Add any type-specific logic for inner exceptions.
      }
      private MyException(SerializationInfo info, 
         StreamingContext context) : base(info, context)
      {
         // Implement type-specific serialization constructor logic.
      }
    }  

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

public class MyException : Exception
{
    public MyException(string message, string extraInfo) : base(message)
    {
        this.Message = $"{message} Extra info: {extraInfo}";
        // You can omit the 'this.' portion above...
    }
}

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

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

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

public class MyException : Exception
{
    public MyException(string message, string extraInfo)
    {
        this.Message = $"{message} Extra info: {extraInfo}";
        // You can omit the 'this.' portion above...
    }
}

نعم ، يمكنك استدعاء طريقة أخرى قبل قاعدة الاتصال أو هذا!

public class MyException : Exception
{
    public MyException(int number) : base(ConvertToString(number)) 
    {
    }

    private static string ConvertToString(int number) 
    { 
      return number.toString()
    }

}




c# constructor