Wywołanie konstruktora bazowego w C#

Jeśli dziedziczę z klasy bazowej i chcę przekazać coś z konstruktora odziedziczonej klasy do konstruktora klasy bazowej, jak to zrobić?

Na przykład,

Jeśli dziedziczę z klasy Exception chcę zrobić coś takiego:

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

Zasadniczo chcę być w stanie przekazać wiadomość tekstową do podstawowej klasy WYJĄTKÓW.

 1192
Author: Peter Mortensen, 2008-08-15

11 answers

Zmodyfikuj swój konstruktor w następujący sposób, aby poprawnie wywołał konstruktor klasy bazowej:

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

Zauważ, że konstruktor nie jest czymś, co można wywołać w każdej chwili w metodzie. To jest powód, dla którego dostajesz błędy w wywołaniu w ciele konstruktora.

 1516
Author: Jon Limjap,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-15 07:48:56

Zauważ, że możesz używać metod static w wywołaniu konstruktora bazowego.

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;
     }
}
 431
Author: Axl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-31 17:17:17

Jeśli musisz wywołać konstruktor bazowy, ale nie od razu, ponieważ twoja nowa (pochodna) klasa musi wykonać pewną manipulację danymi, najlepszym rozwiązaniem jest użycie metody fabrycznej. To, co musisz zrobić, to oznaczyć prywatny konstruktor Pochodny, a następnie utworzyć statyczną metodę w swojej klasie, która wykona wszystkie niezbędne rzeczy, a później wywoła konstruktor i zwróci obiekt.

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);
    }
}
 80
Author: armanali,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-07 20:52:07
public class MyExceptionClass : Exception
{
    public MyExceptionClass(string message,
      Exception innerException): base(message, innerException)
    {
        //other stuff here
    }
}

Możesz przekazać wewnętrzny wyjątek jednemu z konstruktorów.

 22
Author: SnowBEE,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-04 05:03:34

To prawda użyć base (something) do wywołania konstruktora klasy bazowej, ale w przypadku przeciążenia użyj słowa kluczowegothis

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
 19
Author: Janus Pedersen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-09 11:46:52

Z Framework Design Guidelines i FxCop rules.:

1. Niestandardowy wyjątek powinien mieć nazwę kończącą się wyjątkiem

    class MyException : Exception

2. Wyjątek powinien być publiczny

    public class MyException : Exception

3. CA1032: wyjątek powinien implementować standardowe konstruktory.

  • publiczny konstruktor bez parametru.
  • konstruktor publiczny z jednym argumentem łańcuchowym.
  • konstruktor publiczny z jednym ciągiem znaków i wyjątkiem (ponieważ może zawijać inny wyjątek).
  • Konstruktor serializacji chroniony, jeśli Typ nie jest zapieczętowany, a prywatny, Jeśli typ jest zapieczętowany. Na podstawie 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.
      }
    }  
    

Lub

    [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.
      }
    }  
 12
Author: Fab,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-24 07:34:21

Możesz również wykonać sprawdzenie warunkowe z parametrami w konstruktorze, co pozwala na pewną elastyczność.

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

Lub

public MyClass(object myObject=null): base(myObject==null ? new myOtherObject(): myObject)
{
}
 9
Author: wchoward,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-11 10:47:32
class Exception
{
     public Exception(string message)
     {
         [...]
     }
}

class MyExceptionClass : Exception
{
     public MyExceptionClass(string message, string extraInfo)
     : base(message)
     {
         [...]
     }
}
 4
Author: Tutankhamen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-26 04:11:37
public class MyException : Exception
{
    public MyException() { }
    public MyException(string msg) : base(msg) { }
    public MyException(string msg, Exception inner) : base(msg, inner) { }
}
 4
Author: Donat Sasin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-22 13:10:47

Zgodnie z niektórymi innymi odpowiedziami tutaj wymienionymi, możesz przekazać parametry do konstruktora klasy bazowej. Zaleca się wywołanie konstruktora klasy bazowej na początku konstruktora dla odziedziczonej klasy.

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

Zauważam, że w twoim przykładzie nigdy nie użyłeś parametru extraInfo, więc założyłem, że możesz chcieć połączyć parametr extraInfo string z właściwością Message twojego wyjątku (wygląda na to, że jest to ignorowane w zaakceptowanej odpowiedzi i kodzie w odpowiedzi). twoje pytanie).

Jest to po prostu osiągnięte przez wywołanie konstruktora klasy bazowej, a następnie zaktualizowanie właściwości Message o dodatkowe informacje.

Alternatywnie, ponieważ właściwość Message jest dziedziczona z klasy bazowej, nie musisz nawet jawnie wywoływać konstruktora klasy bazowej. Możesz po prostu zaktualizować właściwość Message bezpośrednio z konstruktora odziedziczonej klasy, w następujący sposób:

public class MyException : Exception
{
    public MyException(string message, string extraInfo)
    {
        this.Message = $"{message} Extra info: {extraInfo}";
        // You can omit the 'this.' portion above...
    }
}
 4
Author: Daffy Punk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-23 21:04:22

Używając base możesz wywołać konstruktor klasy bazowej

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

        }
    }
 0
Author: Sunil Dhappadhule,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-10 07:50:56