在 C# 中调用基本构造函数 [重复]
Posted
技术标签:
【中文标题】在 C# 中调用基本构造函数 [重复]【英文标题】:Calling base constructor in C# [duplicate] 【发布时间】:2010-10-12 05:21:49 【问题描述】:我有以下层次结构:
class Base
public Base(string sMessage)
//Do stuff
class Derived : Base
public Derived(string someParams)
string sMessage = "Blah " + someParams;
//Here I want to call the base constructor
//base(sMessage);
【问题讨论】:
【参考方案1】:我最初错过了 OregonGhost 关于使用静态方法修改参数的评论,结果证明这对我来说是最有用的,所以我想我会为阅读此线程的其他人添加代码示例:
class Base
public Base( string sMessage )
// Do stuff
class Derived : Base
public Derived( string sMessage ) : base( AdjustParams( sMessage ) )
static string AdjustParams( string sMessage )
return "Blah " + sMessage;
【讨论】:
【参考方案2】:其实最简单的解决办法是:
class Base
public Base(string sMessage)
//Do stuff
class Derived : Base
public Derived(string someParams)
: base("Blah " + someParams)
为什么要让它更复杂?
【讨论】:
是的,我注意到之后 OregonGhost 已经建议了这个..【参考方案3】:public Derived(string someParams) : base(someParams)
string sMessage = "Blah " + someParams;
这是你必须这样做的方式。你也许可以把你想调用的代码放在基类的一个受保护的方法中,然后你可以像这样调用它:
class Base
public Base(string sMessage)
ConstructorStuff();
protected Base()
protected void ConstructorStuff()
class Derived : Base
public Derived(string someParams)
string sMessage = "Blah " + someParams;
ConstructorStuff();
【讨论】:
这将运行 ConstructorStuff 两次——一次是在派生构造函数之前调用默认基本构造函数时,一次是在派生构造函数执行期间。 呃? Base 没有调用 ConstructorStuff 的默认构造函数? 啊。然后您需要提供一个默认构造函数,否则代码将无法编译,因为您的派生类将需要它。问题仍然存在,默认构造函数也需要使用 ConstructorStuff 并且您需要一个不调用初始化程序的替代方法。 这会让我从一个基本的 C# 问题中错过“太明显而无法打扰”的代码。修改后的代码现在会做他想做的事,不是吗? 现在的问题是每个派生类都需要调用初始化程序。我认为你想要的是默认运行初始化,但如果有必要有办法阻止它。这将完成这项工作,但不是 IMO 的最佳解决方案。【参考方案4】:如果您确实需要首先运行您的构造函数,那么我建议使用受保护的 Initialize 方法,该方法由您的构造函数调用并执行初始化类的实际工作。您需要提供一个允许跳过初始化的替代构造函数。
public class Base
public Base() : this(true)
protected Base(bool runInitializer)
if (runInitializer)
this.Initialize();
protected void Initialize()
...initialize...
public class Derived : Base
// explicitly referencing the base constructor keeps
// the default one from being invoked.
public Derived() : base(false)
...derived code
this.Initialize();
【讨论】:
【参考方案5】:您必须在派生类构造函数的主体之前调用基类构造函数。
class Derived : Base
public Derived(string someParams)
: base("Blah " + someParams)
【讨论】:
这可能是这个简单案例的最佳解决方案,但如果构造参数要复杂得多,它会很快变得丑陋。 确实如此,尽管您也可以在静态方法中构造参数并将结果传递给基类构造函数。我更喜欢这种方法。或者,由于这是 .NET,因此您可以从构造函数中删除内容并在 setter 中执行,这是序列化友好的。【参考方案6】:构造函数需要注意的点:
· 构造函数不能是“虚拟的”。
· 他们不能被继承。
· 构造函数按继承顺序调用。
public Child(string a):base(a)
【讨论】:
【参考方案7】:你不能。你可以先调用它:
public Derived() : base()
或者你必须使用钩子
class Base
protected void init()
public Base(string sMessage)
init();
class Derived : Base
public Derived(string someParams)
string sMessage = "Blah " + someParams;
init();
【讨论】:
既然 Base 构造函数应该做一些事情(可能是 sMessage 的一些事情),这段代码是如何解决他的问题的? 如果你使用钩子,你需要有办法避免调用默认的基础构造函数。请参阅我的答案,通过提供不运行初始化程序的构造函数来避免这种情况。 @wcm:我只是展示了实现 DotnetDude 需要的操作顺序的步骤。看起来他对 C# 的理解足够好,可以从这里更改参数并返回对象以满足他的实际需求。 @Dinah -- 如果没有默认构造函数,这甚至无法编译。如果添加调用 init() 的默认构造函数,则 init() 会被调用两次:一次在基构造函数中,一次在派生构造函数中。如果你使用钩子实现,你需要有一个不运行它的构造函数。以上是关于在 C# 中调用基本构造函数 [重复]的主要内容,如果未能解决你的问题,请参考以下文章