为什么第一个语句编译而不是第二个?

And*_*rsJ -1 delphi

见下面的代码.它是ClientDataSet的AfterOpen事件.
为什么第二个语句不编译?
错误消息是:Undeclared标识符:'LogChanges'
第三个语句编译.
第三个陈述是否正确,相当于第一个陈述?
如果'DataSet'无法使用,为什么会通过?

procedure TCTL_Configurator_form.cdsZonesAfterOpen(DataSet: TDataSet);
begin
  cdsZones.LogChanges                 := FALSE; // This line compiles
  DataSet.LogChanges                  := FALSE; // This line does NOT compile
  TClientDataSet(DataSet).LogChanges  := FALSE; // This line compiles
end;
Run Code Online (Sandbox Code Playgroud)

Ken*_*ite 5

TDataSet没有方法LogChanges.它被引入TClientDataSet,这就是第三行编译的原因; 你有DataSet更具体的类型TClientDataSet.正如Anthony在评论中指出的那样,如果DataSet实际上不是TClientDataSet或TClientDataSet的后代,则类型转换将在运行时导致访问冲突 - 更好的选择是(DataSet as TClientDataSet)用于检查或使用if DataSet is TClientDataSet.

AfterOpen事件被引入TDataSet,它接收一个普通的旧TDataSet参数.