我想澄清一个疑问。在我当前的项目中,我发现有两个TClientDataSet组件。并将一个客户端数据集的属性和事件处理程序分配给另一个客户端数据集,如下所示:
cds2.AfterApplyUpdates := cds1.AfterApplyUpdates;
cds2.AfterCancel := cds1.AfterCancel;
cds2.AfterClose := cds1.AfterClose;
并且
cds2.CommandText := cds1.CommandText;
cds2.AutoCalcFields := cds1.AutoCalcFields;
cds2.DisableStringTrim := cds1.DisableStringTrim;
是否需要上述事件处理程序和属性分配?
如果我们只是将一个客户端数据集分配给另一个,如下所示,这还不够吗?
cds2 := cds1;
答案 0 :(得分:15)
Delphi类是引用类型。这意味着当您定义一个类型为类的变量时,您实际拥有的是对象的引用或指针。这使赋值运算符:=
的含义成为引用赋值而不是值赋值。
假设您有以下声明:
var
o1, o2: TObject;
....
o1 := TObject.Create;
o2 := o1;
此时,您创建了一个对象,o1
和o2
都引用或指向同一个对象。您通过o1
引用所做的任何更改也可通过o2
引用显示,因为只有一个对象或实例。
因此,在您的方案中,您有cds1
和cds2
,大概是指不同的实例。这意味着
cds2.CommandText := cds1.CommandText;
将cds1.CommandText
的值复制到cds2.CommandText
。
与
完全不同cds2 := cds1;
复制引用,导致您忘记cds2
引用的单独对象。
在此处查找有关参考类型和值类型的更多讨论:Why should we use classes rather than records, or vice versa?。
总之,您提出的两个选项会做很多不同的事情。您当前使用的代码复制属性值,可能会起作用。在这种情况下,您建议的复制引用更改肯定不会达到您想要的效果。
答案 1 :(得分:2)
首先:所有组件事件实际上只是引用事件方法的属性,然后将事件方法用作事件处理程序。所以,当你把一个事件作为
cds2.AfterApplyUpdates := cds1.AfterApplyUpdates;
您只是指定对同一方法的引用。 对于事件,这是非常常用的,以避免多次编写相同的代码。
其次:当你使用
将一个对象变量分配给另一个对象时,大卫已经很伤心了cds2 := cds1;
您只是将对象实例的相同引用分配给另一个变量。您没有复制该对象的任何实际数据。
第三,即使你问的问题会起作用,我怀疑你会不会想要使用它。为什么?因此,您将获得两个将访问相同数据库的TClientDataSets。而拥有这些只是一点点。