наследование - порядок вызова конструкторов c#




Вызов базового конструктора в C# (8)

В соответствии с некоторыми другими приведенными здесь ответами вы можете передавать параметры в конструктор базового класса. Рекомендуется назначить конструктор базового класса в начале конструктора для вашего унаследованного класса.

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 с extraInfo Message вашего исключения (кажется, что это игнорируется в принятом ответе, а код в ваш вопрос).

Это просто достигается путем вызова конструктора базового класса и последующего обновления свойства 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...
    }
}

Если я наследую базовый класс и хочу передать что-то из конструктора унаследованного класса в конструктор базового класса, как это сделать?

Например,

Если я наследую класс Exception, я хочу сделать что-то вроде этого:

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

В основном я хочу, чтобы передать строковое сообщение в базовый класс Exception.


Верно использовать 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 MyClass : BaseClass
{
    private MyClass(string someString) : base(someString)
    {
        //your code goes in here
    }

    public static MyClass FactoryMethod(string someString)
    {
        //whatever you want to do with your string before passing it in
        return new MyClass(someString);
    }
}

Измените свой конструктор следующим образом, чтобы он правильно вызвал конструктор базового класса:

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

Обратите внимание, что конструктор не является тем, что вы можете вызвать в любое время в рамках метода. Именно по этой причине вы получаете ошибки в своем вызове в теле конструктора.


Из Руководства по разработке рамок и правил FxCop. :

1. Пользовательское исключение должно иметь имя, которое заканчивается Исключением

    class MyException : Exception

2. Исключение должно быть общедоступным

    public class MyException : Exception

3. CA1032: Исключение должно реализовывать стандартные конструкторы.

  • Открытый конструктор без параметров.
  • Открытый конструктор с одним строковым аргументом.
  • Открытый конструктор с одной строкой и Exception (поскольку он может обернуть другое исключение).
  • Конструктор сериализации защищен, если тип не запечатан и не закрыт, если тип запечатан. На основе 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.
      }
    }  

используя базу, вы можете вызвать конструктор базового класса

class BaseClass
    {

    public BaseClass(int val)
    {
        Console.WriteLine($"{nameof(BaseClass) } constructor");
    }
   }

    class DerivedClass : BaseClass
    {
    public DerivedClass() : base(10)
    {
        Console.WriteLine($"{nameof(DerivedClass) } constructor");
    }
    }
    class Program
    {
        static void Main(string[] args)
        {
        BaseClass baseClass = new DerivedClass();
          Console.ReadLine();

        }
    }

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
    }
}

Вы можете передать внутреннее исключение одному из конструкторов.







constructor