Chamando o construtor base em C#
-
08-06-2019 - |
Pergunta
Se eu herdar de uma classe base e quiser passar algo do construtor da classe herdada para o construtor da classe base, como faço isso?
Por exemplo,
Se eu herdar da classe Exception, quero fazer algo assim:
class MyExceptionClass : Exception
{
public MyExceptionClass(string message, string extraInfo)
{
//This is where it's all falling apart
base(message);
}
}
Basicamente, o que eu quero é poder passar a mensagem da string para a classe base Exception.
Solução
Modificar o construtor para o seguinte para que ele chama o construtor da classe base corretamente:
public class MyExceptionClass : Exception
{
public MyExceptionClass(string message, string extrainfo) : base(message)
{
//other stuff here
}
}
Note que um construtor não é algo que você pode chamar a qualquer momento dentro de um método. Essa é a razão que você está recebendo erros em sua chamada no corpo do construtor.
Outras dicas
Note que você pode usar estática métodos dentro da chamada para o construtor base.
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;
}
}
Se você precisar chamar o construtor base, mas não imediatamente porque seus novos (derivados) necessidades de classe para fazer alguma manipulação de dados, a melhor solução é recorrer a método de fábrica. O que você precisa fazer é marcar privada seu construtor derivada, em seguida, fazer um método estático em sua classe que vai fazer todo o material necessário e depois chamar o construtor e retornar o objeto.
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);
}
}
É verdade utilização do base
(algo) para chamar o construtor da classe base, mas em caso de sobrecarga uso do this
palavra-chave
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 MyExceptionClass : Exception
{
public MyExceptionClass(string message,
Exception innerException): base(message, innerException)
{
//other stuff here
}
}
Você pode passar de exceção interna para um dos construtores.
de Guia de design Framework e regras FxCop :.
1. Exceção personalizado deve ter um nome que termina com exceção
class MyException : Exception
2. Exceção deve ser pública
public class MyException : Exception
3. CA1032:. exceção deve implementos construtores padrão
- Um construtor sem parâmetros público.
- Um construtor público com o argumento um string.
- Um construtor público com uma corda e de exceção (como ele pode quebrar outra exceção).
-
Um construtor de serialização protegidos se o tipo não é selado e privado, se o tipo está selado. Baseado em 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. } }
ou
[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.
}
}
Você também pode fazer uma verificação condicional com parâmetros no construtor, que permite alguma flexibilidade.
public MyClass(object myObject=null): base(myObject ?? new myOtherObject())
{
}
ou
public MyClass(object myObject=null): base(myObject==null ? new myOtherObject(): myObject)
{
}
class Exception
{
public Exception(string message)
{
[...]
}
}
class MyExceptionClass : Exception
{
public MyExceptionClass(string message, string extraInfo)
: base(message)
{
[...]
}
}
public class MyException : Exception
{
public MyException() { }
public MyException(string msg) : base(msg) { }
public MyException(string msg, Exception inner) : base(msg, inner) { }
}
De acordo com alguns dos outros respostas listadas aqui, você pode passar parâmetros para o construtor da classe base. Aconselha-se a chamar seu construtor da classe base no início do construtor para a sua classe herdada.
public class MyException : Exception
{
public MyException(string message, string extraInfo) : base(message)
{
}
}
Faço notar que no seu exemplo você nunca fez uso do parâmetro extraInfo
, então eu assumi que você pode querer concatenar o parâmetro de cadeia extraInfo
à propriedade Message
de sua exceção (parece que este está a ser ignorado na resposta aceita e o código na sua pergunta).
Isto é simplesmente alcançado invocando o construtor da classe base, e em seguida, atualizar a propriedade da mensagem com a informação extra.
public class MyException: Exception
{
public MyException(string message, string extraInfo) : base($"{message} Extra info: {extraInfo}")
{
}
}