【发布时间】:2017-08-29 07:26:53
【问题描述】:
我对许多其他线程中的分配代码感到困惑,例如,这个: See the Assign method implementation given in an answer.
procedure TDispPitch.Assign(Source: TPersistent);
var
LSource: TDispPitch;
begin
if Source is TDispPitch then
begin
LSource := TDispPitch(Source);
iLineSize := LSource.LineSize;
iLineColor := LSource.LineColor;
bDisplayAccent := LSource.DisplayAccent;
bVisible := LSource.Visible;
Changed;
end else
inherited;
end;
但是如果对inherited的调用在Else部分,那么基类属性是如何分配给满足if条件的对象的呢?将此与 VCL 自己的 TStringList 代码进行比较。
procedure TStringList.Assign(Source: TPersistent);
begin
inherited Assign(Source);
if Source is TStringList then
begin
FCaseSensitive := TStringList(Source).FCaseSensitive;
...
end;
end;
这会首先正确调用 Inherited,以便首先分配基类属性。
那么第一个代码块对吗?我在堆栈溢出的许多地方都发现了这样的代码。我无法理解如何在该代码中分配基类属性。有人可以解释吗?另一方面,如果代码错误,为什么没有人在所有这些线程中指出它?
【问题讨论】:
-
这取决于是否有任何基类属性。无法判断从其上下文中删除的第一个代码示例。您显然对所有部件的工作方式有一个完美的了解。我相信你可以自己评估代码。
-
感谢您的意见。我想从最佳实践的角度来理解它。我认为上面的 VCL 代码总是可以工作的。我不明白的是第一个代码中“else”的使用。总是先调用继承有什么害处?我想我需要了解流媒体系统如何使用它。所有讨论基于 TCollectionItem 和 TOwnedCollection 的类的代码示例都使用这种代码。
-
else 是将执行引导到
TPersistent.Assign,它调用Source.AssignTo(Self)并为Source实例提供实现分配操作的机会。这为一个类提供了一种机制,实际上,在另一个类中实现Assign而无需修改另一个类。如果您只是阅读源代码,我相信您可以理解这一点。你明白inherited是什么意思。 -
让我换个方式问这个问题。当我从另一个组件派生一个组件时,第二种编码形式不是最安全的吗?我知道我在派生组件中添加了哪些属性。我可以在不查看基础来源的情况下编写代码,这对我来说似乎是多余的事情。那为什么不像构造函数那样形成一个标准,每个人都先调用继承,然后设置新的属性值?
-
但是让我们弄清楚问题中的两个代码块。他们都是正确的。它们因阶级的不同遗产而有所不同。这里没有一种适合所有解决方案的尺寸。如果您花时间理解为什么这两个
Assign实现不同,通过阅读源代码,您将能够在编写自己的代码时做出正确的决定。
标签: delphi