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); } } |
确实,使用
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 |
或
1 2 3 |
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) { } } |
我注意到在您的示例中,您从未使用过
这只需调用基类构造函数,然后用额外的信息更新消息属性即可实现。
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) { [...] } } |