关于继承:在C中调用基构造函数#

关于继承:在C中调用基构造函数#

Calling the base constructor in C#

如果我继承了一个基类,并且想将继承类的构造函数中的某些内容传递给基类的构造函数,我该怎么做呢?

例如,

如果我从异常类继承,我想这样做:

1
2
3
4
5
6
7
8
class MyExceptionClass : Exception
{
     public MyExceptionClass(string message, string extraInfo)
     {
         //This is where it's all falling apart
         base(message);
     }
}

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


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

1
2
3
4
5
6
7
public class MyExceptionClass : Exception
{
    public MyExceptionClass(string message, string extrainfo) : base(message)
    {
        //other stuff here
    }
}

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


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

1
2
3
4
5
6
7
8
9
10
11
12
13
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;
     }
}


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

1
2
3
4
5
6
7
8
9
10
11
12
13
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);
    }
}

确实,使用base来调用基类构造函数,但在重载的情况下,使用this关键字

1
2
3
4
5
6
7
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

1
2
3
4
5
6
7
8
public class MyExceptionClass : Exception
{
    public MyExceptionClass(string message,
      Exception innerException): base(message, innerException)
    {
        //other stuff here
    }
}

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


来自框架设计指南和fxcop规则:

1。自定义异常应具有以异常结尾的名称

1
    class MyException : Exception

2。异常应该是公共的

1
    public class MyException : Exception

三。CA1032:异常应实现标准构造函数。

  • 公共无参数构造函数。
  • 具有一个字符串参数的公共构造函数。
  • 具有一个字符串和异常(因为它可以包装另一个异常)的公共构造函数。
  • 如果类型不是密封的,则是受保护的序列化构造函数;如果类型是密封的,则是私有的。基于MSDN:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    [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.
      }
    }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
    [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.
      }
    }


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

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

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

1
2
3
4
5
6
public class MyException : Exception
{
    public MyException() { }
    public MyException(string msg) : base(msg) { }
    public MyException(string msg, Exception inner) : base(msg, inner) { }
}

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

1
2
3
4
5
6
public class MyException : Exception
{
    public MyException(string message, string extraInfo) : base(message)
    {
    }
}

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

这只需调用基类构造函数,然后用额外的信息更新消息属性即可实现。

1
2
3
4
5
6
public class MyException: Exception
{
    public MyException(string message, string extraInfo) : base($"{message} Extra info: {extraInfo}")
    {
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Exception
{
     public Exception(string message)
     {
         [...]
     }
}

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


推荐阅读

    pythonpip怎么调用

    pythonpip怎么调用,培训,工具,标准,管理,替代品,模块,以上,功能,更多,内容,p

    python支持多继承吗

    python支持多继承吗,培训,代码,不了,上边,函数,属性,例子,父亲,定义,母亲,py

    python库怎么调用

    python库怎么调用,培训,模块,代码,成员,别名,前缀,程序,语句,语法,上面,pyth

    python如何实现继承

    python如何实现继承,培训,概念,名称,方法,定义,个人,属性,接口,过程,能力,py

    python怎么调用random

    python怎么调用random,培训,模块,整数,方法,范围内,不是,以内,元素,命令,以

    python类的继承机制

    python类的继承机制,代码,培训,方法,定义,对象,机制,口感,语法,圆括号,水果

    python构造函数有什么用

    python构造函数有什么用,代码,培训,名字,方法,参数,对象,函数,结尾,开头,实

    python怎么调用实例方法

    python怎么调用实例方法,代码,培训,方法,对比,参数,实例,空间,变量,定义,函

    python如何调用函数

    python如何调用函数,代码,培训,函数,名字,工作,处分,较大,变量,程序,定义,函

    python如何调用mysql

    python如何调用mysql,培训,流程,一致,密码,数据,数据库,数据库连接,接口,

    python怎么调用类方法

    python怎么调用类方法,培训,方法,实例,静态,定义,参数,属性,对象,关键字,以

    python可以多继承吗

    python可以多继承吗,代码,培训,不了,方法,属性,父亲,孩子,前缀,上边,变量,py

    python库怎么调用

    python库怎么调用,第三,培训,环境,工具,管理,系统,源码,语句,文件夹,命令,py