如何调用构造函数初始化器base()和this() ?
本文关键字:base this 构造函数 何调用 调用 初始化 | 更新日期: 2023-09-27 18:02:25
这很容易解决,但我只是好奇我是否可以使用语言功能,或者可能是语言不允许的事实意味着我在类设计中犯了逻辑错误。
我正在对我的代码进行自我检查,以帮助"强化"它以供重用,然后我偶然发现:
public partial class TrackTyped : Component
{
IContainer components = null;
public TrackTyped()
: base()
{
InitializeComponent();
}
public TrackTyped(IContainer container)
: base()
{
container.Add(this);
InitializeComponent();
}
}
当我在两个构造函数中看到同一行代码时,我通常做的是用"this()"调用另一个,但我似乎不能这样做。
如果我没看错说明书(我刚开始试着看说明书,所以我可能看错了):
10.11 Instance Constructors
constructor-declarator:
identifier ( formal-parameter-listopt ) constructor-initializeropt
constructor-initializer:
: base ( argument-listopt )
: this ( argument-listopt )
它说我只能有其中一个
问题:10.11是否暗示没有理由需要调用两者,还是仅仅暗示语言只支持调用一个?
不需要调用这两个,因为this
重定向到另一个将调用base
的构造函数
你不知道,也不能。您可以通过:this(...)
将构造函数调用转发给同类的另一个构造函数。该链中的最后一个构造函数必须通过:base(...)
隐式或显式初始化基类。
假设类A有两个构造函数。一个用:base(2)
初始化base,另一个用:base(3)
初始化base。如果允许第一个构造函数也指定:this (/*call the other ctor*/)
,那么基数应该如何初始化:用2还是3?这就是为什么这些东西不允许
这似乎是你想要的:
public partial class TrackTyped : Component
{
IContainer components = null;
public TrackTyped()
: base()
{
InitializeComponent();
}
public TrackTyped(IContainer container)
: this()
{
container.Add(this);
}
}
但是,现在第二个构造函数中的语句顺序不同了。如果这很重要,那么就没有真正的好方法来做您想做的事情,因为即使您有相同的行,功能也有微妙的不同。在这种情况下,你只需要重复这条线。别担心。
你没有看错规范:它必须是其中之一。
通常在有多个属性要通过构造函数初始化的类中完成,其中一些属性是可选的。我们有一个最大的构造函数,它接受所有形参,调用基类构造函数。所有其他构造函数都通过向这个大构造函数传递一个null/默认值来重定向到这个构造函数。这样,所有的初始化代码都保存在一个地方,可以被其他人重用。
public MissingEntityException(Type type, string criteria, string message = "")
: this(type, criteria, message, null)
{
}
public MissingEntityException(Type type, string criteria, string message, Exception innerException)
: base(message, innerException)
{
this.EntityType = type;
this.Criteria = criteria;
}
这是跨层次结构支持的,可以涉及任何数量或参数。
这是你要找的吗?
public partial class TrackTyped : Component
{
IContainer components = null;
public TrackTyped() : base()
{
// logic for InitializeComponent() here
}
public TrackTyped(IContainer container) : this()
{
container.Add(this)
}
}
btw:这是第二个元素的一个有趣的用法:
var a = TrackTyped(container);
我想知道是否删除第二个元素并这样做对你来说会更清楚?(相同的结果)
container.Add(new TrackTyped());