Вызов базового конструктора в C # - PullRequest
1310 голосов
/ 15 августа 2008

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

Например,

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

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

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

Ответы [ 10 ]

1646 голосов
/ 15 августа 2008

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

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

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

464 голосов
/ 28 апреля 2010

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

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;
     }
}
88 голосов
/ 27 февраля 2013

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

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);
    }
}
28 голосов
/ 11 ноября 2013

Это правда, используйте 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
25 голосов
/ 04 декабря 2009
public class MyExceptionClass : Exception
{
    public MyExceptionClass(string message,
      Exception innerException): base(message, innerException)
    {
        //other stuff here
    }
}

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

18 голосов
/ 24 января 2016

Из Руководства по проектированию платформы и правила 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.
      }
    }  
13 голосов
/ 28 мая 2016

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

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

или

public MyClass(object myObject=null): base(myObject==null ? new myOtherObject(): myObject)
{
}
7 голосов
/ 07 апреля 2016
public class MyException : Exception
{
    public MyException() { }
    public MyException(string msg) : base(msg) { }
    public MyException(string msg, Exception inner) : base(msg, inner) { }
}
7 голосов
/ 26 февраля 2015
class Exception
{
     public Exception(string message)
     {
         [...]
     }
}

class MyExceptionClass : Exception
{
     public MyExceptionClass(string message, string extraInfo)
     : base(message)
     {
         [...]
     }
}
6 голосов
/ 14 марта 2017

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

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

Я отмечаю, что в вашем примере вы никогда не использовали параметр extraInfo, поэтому я предположил, что вы можете объединить строковый параметр extraInfo со свойством Message вашего исключения (похоже, это происходит игнорируется в принятом ответе и коде в вашем вопросе).

Это просто достигается путем вызова конструктора базового класса, а затем обновления свойства Message с дополнительной информацией.

public class MyException: Exception
{
    public MyException(string message, string extraInfo) : base($"{message} Extra info: {extraInfo}")
    {
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...