在 C# 中调用基本构造函数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12051/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-01 08:43:46  来源:igfitidea点击:

Calling the base constructor in C#

提问by lomaxx

If I inherit from a base class and want to pass something from the constructor of the inherited class to the constructor of the base class, how do I do that?

如果我从基类继承并想将继承类的构造函数传递给基类的构造函数,我该怎么做?

For example, if I inherit from the Exception class I want to do something like this:

例如,如果我从 Exception 类继承,我想做这样的事情:

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

Basically what I want is to be able to pass the string message to the base Exception class.

基本上我想要的是能够将字符串消息传递给基类 Exception 。

采纳答案by Jon Limjap

Modify your constructor to the following so that it calls the base class constructor properly:

将构造函数修改为以下内容,以便它正确调用基类构造函数:

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

Note that a constructor is not something that you can call anytime within a method. That's the reason you're getting errors in your call in the constructor body.

请注意,构造函数不是您可以在方法中随时调用的东西。这就是您在构造函数体的调用中出错的原因。

回答by SnowBEE

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.

您可以将内部异常传递给构造函数之一。

回答by Axl

Note that you can use staticmethods within the call to the base constructor.

请注意,您可以在对基本构造函数的调用中使用静态方法。

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

回答by armanali

If you need to call the base constructor but not right away because your new (derived) class needs to do some data manipulation, the best solution is to resort to factory method. What you need to do is to mark private your derived constructor, then make a static method in your class that will do all the necessary stuff and later call the constructor and return the object.

如果您需要调用基构造函数但不是立即调用,因为您的新(派生)类需要进行一些数据操作,最好的解决方案是诉诸工厂方法。您需要做的是将您的派生构造函数标记为私有,然后在您的类中创建一个静态方法,该方法将执行所有必要的操作,然后调用构造函数并返回对象。

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

回答by Janus Pedersen

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

确实使用base(something) 来调用基类构造函数,但在重载的情况下使用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

回答by Tutankhamen

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

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

回答by Fab

From Framework Design Guidelinesand FxCop rules.:

来自框架设计指南和 FxCop 规则。

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

1.自定义异常应该有一个以Exception结尾的名字

    class MyException : Exception

2. Exception should be public

2. 异常应该是公开的

    public class MyException : Exception

3. CA1032: Exception should implements standard constructors.

3. CA1032:异常应该实现标准构造函数。

  • 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.
      }
    }  
    
  • 公共无参数构造函数。
  • 带有一个字符串参数的公共构造函数。
  • 带有一个字符串和异常的公共构造函数(因为它可以包装另一个异常)。
  • 如果类型未密封则序列化构造函数受保护,如果类型已密封则为私有。基于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.
      }
    }  

回答by Donat Sasin

public class MyException : Exception
{
    public MyException() { }
    public MyException(string msg) : base(msg) { }
    public MyException(string msg, Exception inner) : base(msg, inner) { }
}

回答by dynamiclynk

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

回答by CShark

As per some of the other answers listed here, you can pass parameters into the base class constructor. It is advised to call your base class constructor at the beginning of the constructor for your inherited class.

根据此处列出的其他一些答案,您可以将参数传递给基类构造函数。建议在继承类的构造函数的开头调用基类构造函数。

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

I note that in your example you never made use of the extraInfoparameter, so I assumed you might want to concatenate the extraInfostring parameter to the Messageproperty of your exception (it seems that this is being ignored in the accepted answer and the code in your question).

我注意到,在您的示例中,您从未使用过该extraInfo参数,因此我假设您可能希望将extraInfo字符串参数连接到Message您的异常的属性(这似乎在接受的答案和您的问题中的代码中被忽略了) .

This is simply achieved by invoking the base class constructor, and then updating the Message property with the extra info.

这只是通过调用基类构造函数,然后使用额外信息更新 Message 属性来实现的。

public class MyException: Exception
{
    public MyException(string message, string extraInfo) : base($"{message} Extra info: {extraInfo}")
    {
    }
}