在C#中调用基构造函数

如果我从一个基类继承,并希望从继承类的构造函数传递一些东西给基类的构造函数,我该怎么做?

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

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

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

1301001 次浏览

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

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

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

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

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

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

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

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

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 inreturn new MyClass(someString);}}

使用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

框架设计指南和FxCop规则。

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

    class MyException : Exception

2.例外应当是公开的

    public class MyException : Exception

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

  • 公共无参数构造函数。
  • 具有一个字符串参数的公共构造函数。
  • 具有一个字符串和Exception的公共构造函数(因为它可以包装另一个Exception)。
  • 如果类型未密封,则受保护的序列化构造函数;如果类型已密封,则为私有。基于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.}}
public class MyException : Exception{public MyException() { }public MyException(string msg) : base(msg) { }public MyException(string msg, Exception inner) : base(msg, inner) { }}

您还可以使用构造函数中的参数进行条件检查,这允许一定的灵活性。

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

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

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

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

使用较新的C#特性,即out var,您可以摆脱静态工厂方法。我刚刚发现(偶然)称为inse base的方法的out var参数-“call”流向构造函数主体。

例如,使用您想要派生的基类:

public abstract class BaseClass{protected BaseClass(int a, int b, int c){}}

您要执行的非编译伪代码:

public class DerivedClass : BaseClass{private readonly object fatData;
public DerivedClass(int m){var fd = new { A = 1 * m, B = 2 * m, C = 3 * m };base(fd.A, fd.B, fd.C); // base-constructor callthis.fatData = fd;}}

解决方案是使用静态私有helper方法,该方法生成所有必需的基本参数(如果需要,还可以添加额外的数据),而不使用静态工厂方法,只需向外部提供普通构造函数:

public class DerivedClass : BaseClass{private readonly object fatData;
public DerivedClass(int m): base(PrepareBaseParameters(m, out var b, out var c, out var fatData), b, c){this.fatData = fatData;Console.WriteLine(new { b, c, fatData }.ToString());}
private static int PrepareBaseParameters(int m, out int b, out int c, out object fatData){var fd = new { A = 1 * m, B = 2 * m, C = 3 * m };(b, c, fatData) = (fd.B, fd.C, fd); // Tuples not required but nice to usereturn fd.A;}}