2016-04-04 12 views
-1

以下のコードを参照してください。これは、ClientDataSetのAfterOpenイベントです。
2番目のステートメントがコンパイルされないのはなぜですか?
エラーメッセージは次のとおりです。宣言されていない識別子: 'LogChanges'
3番目のステートメントがコンパイルされます。
3番目のステートメントは正しいですか?最初のステートメントと同じですか?
'DataSet'を使用できない場合、なぜそれが渡されますか?最初のステートメントはなぜコンパイルされますが、2番目のステートメントはコンパイルされませんか?

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; 
+0

イベントが「TClientDataSet」またはその子孫でない 'DataSet'を渡された場合、3番目のオプションが実行時にアクセス違反で失敗する可能性があることに注意してください。 – afrazier

+0

私は私の質問の3行目でコンプライアーエラーに言及します。 – AndersJ

+0

afrazierでは、イベントは、元々ダブルクリックして作成したデータセットからのみ呼び出されます。同じイベントが他のデータセットからも呼び出された場合、アクセス違反が発生する可能性がありますか?もしそうなら、もっと良い方法がありますか? – AndersJ

答えて

5

TDataSetはメソッドLogChangesを持っていません。 TClientDataSetで紹介されています。そのため、3行目がコンパイルされます。 DataSetをより具体的にTClientDataSetにタイプキャストしました。 Anthonyがコメントで指摘したように、データセットが実際にTClientDataSetまたはTClientDataSetの子孫でない場合は、型キャストによって実行時にアクセス違反が発生します。(DataSet as TClientDataSet)を使用してチェックするか、if DataSet is TClientDataSetを使用することをお勧めします。

にはAfterOpenイベントが導入され、平文の古いTDataSetがパラメータとして受信されます。

+0

私は型キャストを使うので、まったく同じステートメントを他のものに使うことができます。より類似したデータセットが追加された場合、将来のコピー/貼り付けエラーを回避することができると考えています。型キャストはこれを行う良い方法か悪い方法ですか? – AndersJ

+0

'TClientDataSet'、Andersの子孫である他のデータセットについてはうまくいきますが、* checked *型のキャストを代わりに使用することをお勧めします。これは、 'as'演算子を使用する種類です。 (実際にこのイベントハンドラを複数のオブジェクトのイベントにアタッチしている場合は、そのメソッドに1つの特定のオブジェクトにしか見えない、より一般的な名前を与えることをお勧めします) –

+0

私は不明確かもしれないと思いますここに。私は複数のクライアントデータセットに1つのイベントを添付していません。私は多くの似たようなクライアントデータセットを持っており、同じようにコード化されたイベントをできる限り多く持つことを好みます。将来私が別のものを必要とし、コピー/貼り付けをすると、修正することが少なくなります。この特定のケースに該当するチェックされた型キャストの例を挙げることができますか? – AndersJ

関連する問題