Вопрос: Вызов базового конструктора в C #


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

Например,

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

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

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


1126


источник


Ответы:


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

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

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


1442



Обратите внимание, что вы можете использовать статический методов в вызове базового конструктора.

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

413



Если вам нужно вызвать базовый конструктор, но не сразу, потому что ваш новый (производный) класс должен выполнять некоторые манипуляции с данными, лучшим решением является использование метода фабрики. Что вам нужно сделать, это отметить частный производный конструктор, а затем создать в своем классе статический метод, который сделает все необходимое, а затем вызовет конструктор и вернет объект.

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

76



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

You can pass inner exception to one of the constructors.


21



It is true use the base (something) to call the base class constructor, but in case of overloading use the this keyword

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

16



From Framework Design Guidelines and FxCop rules.:

1. Custom Exception should have a name that ends with Exception

    class MyException : Exception

2. Exception should be public

    public class MyException : Exception

3. CA1032: Exception should implements standard constructors.

  • A public parameterless constructor.
  • A public constructor with one string argument.
  • A public constructor with one string and Exception (as it can wrap another Exception).
  • A serialization constructor protected if the type is not sealed and private if the type is sealed. Based on 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.
      }
    }  
    

or

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

13



You can also do a conditional check with parameters in the constructor, which allows some flexibility.

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

or

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

7



class Exception
{
     public Exception(string message)
     {
         [...]
     }
}

class MyExceptionClass : Exception
{
     public MyExceptionClass(string message, string extraInfo)
     : base(message)
     {
         [...]
     }
}

4