lom*_*axx 1398 c# inheritance constructor
如果我从一个基类继承并希望将继承类的构造函数中的某些东西传递给基类的构造函数,我该怎么做?
例如,
如果我从Exception类继承,我想做这样的事情:
class MyExceptionClass : Exception
{
public MyExceptionClass(string message, string extraInfo)
{
//This is where it's all falling apart
base(message);
}
}
Run Code Online (Sandbox Code Playgroud)
基本上我想要的是能够将字符串消息传递给基本的Exception类.
Jon*_*jap 1736
将构造函数修改为以下内容,以便它正确调用基类构造函数:
public class MyExceptionClass : Exception
{
public MyExceptionClass(string message, string extrainfo) : base(message)
{
//other stuff here
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,构造函数不是您可以在方法中随时调用的东西.这就是你在构造函数体中调用错误的原因.
Axl*_*Axl 490
请注意,您可以在对基础构造函数的调用中使用静态方法.
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;
}
}
Run Code Online (Sandbox Code Playgroud)
arm*_*ali 95
如果您需要调用基础构造函数但不是立即调用,因为新(派生)类需要进行一些数据操作,最好的解决方案是采用工厂方法.你需要做的是标记私有你的派生构造函数,然后在你的类中创建一个静态方法,它将执行所有必要的东西,然后调用构造函数并返回对象.
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);
}
}
Run Code Online (Sandbox Code Playgroud)
小智 33
确实使用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
Run Code Online (Sandbox Code Playgroud)
Sno*_*BEE 26
public class MyExceptionClass : Exception
{
public MyExceptionClass(string message,
Exception innerException): base(message, innerException)
{
//other stuff here
}
}
Run Code Online (Sandbox Code Playgroud)
您可以将内部异常传递给其中一个构造函数.
Fab*_*Fab 19
来自框架设计指南和FxCop规则.:
1.自定义异常的名称应以Exception结尾
class MyException : Exception
Run Code Online (Sandbox Code Playgroud)
2.例外应该是公开的
public class MyException : Exception
Run Code Online (Sandbox Code Playgroud)
序列化构造函数在类型未密封时受到保护,如果类型被密封则为私有.基于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.
}
}
Run Code Online (Sandbox Code Playgroud)要么
[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.
}
}
Run Code Online (Sandbox Code Playgroud)
wch*_*ard 15
您还可以在构造函数中使用参数进行条件检查,这允许一些灵活性.
public MyClass(object myObject=null): base(myObject ?? new myOtherObject())
{
}
Run Code Online (Sandbox Code Playgroud)
要么
public MyClass(object myObject=null): base(myObject==null ? new myOtherObject(): myObject)
{
}
Run Code Online (Sandbox Code Playgroud)
class Exception
{
public Exception(string message)
{
[...]
}
}
class MyExceptionClass : Exception
{
public MyExceptionClass(string message, string extraInfo)
: base(message)
{
[...]
}
}
Run Code Online (Sandbox Code Playgroud)
根据此处列出的其他一些答案,您可以将参数传递给基类构造函数.建议在继承类的构造函数的开头调用基类构造函数.
public class MyException : Exception
{
public MyException(string message, string extraInfo) : base(message)
{
}
}
Run Code Online (Sandbox Code Playgroud)
我注意到在您的示例中您从未使用过该extraInfo
参数,因此我假设您可能希望将extraInfo
字符串参数连接到Message
异常的属性(似乎在接受的答案和问题中的代码中忽略了这一点) .
这可以通过调用基类构造函数,然后使用额外信息更新Message属性来实现.
或者,由于extraInfo
属性是从基类继承的,因此您甚至不必显式调用基类构造函数.您可以extraInfo
直接从继承类的构造函数更新属性,如下所示:
public class MyException: Exception
{
public MyException(string message, string extraInfo) : base($"{message} Extra info: {extraInfo}")
{
}
}
Run Code Online (Sandbox Code Playgroud)
使用较新的 C# 特性,即out var
,您可以摆脱静态工厂方法。我刚刚发现(偶然)称为 inse base-“call” 的方法的 out var 参数流向构造函数体。
例如,使用您想要派生的这个基类:
public abstract class BaseClass
{
protected BaseClass(int a, int b, int c)
{
}
}
Run Code Online (Sandbox Code Playgroud)
要执行的非编译伪代码:
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 call
this.fatData = fd;
}
}
Run Code Online (Sandbox Code Playgroud)
解决方案是使用静态私有辅助方法,该方法生成所有必需的基本参数(如果需要,还可以添加其他数据),并且不使用静态工厂方法,只需向外部简单构造函数即可:
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 use
return fd.A;
}
}
Run Code Online (Sandbox Code Playgroud)
public class MyException : Exception
{
public MyException() { }
public MyException(string msg) : base(msg) { }
public MyException(string msg, Exception inner) : base(msg, inner) { }
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
978207 次 |
最近记录: |