8


2

withステートメントを使用して作成されたオブジェクトインスタンスを参照する方法はありますか?

例:

TAnObject.CreateでDoSomething(インスタンス)を開始します。終わり;

DoSomethingがインスタンス宣言を、変数宣言された参照から作成されたオブジェクトへのインスタンスを渡しているかのように使用します。

例:

AnObject:= TAnObject.Create;

ありがとう。

9 Answer


14


まあ、あなたはそのようなアプローチを使うことができます:

// implement:

type TSimpleMethod =オブジェクトの手続き。

関数GetThis(const pr:TSimpleMethod):TObject;開始結果:= TMethod(pr).Data;終わり;

// usage:

TStringList.CreateでCommaText:= '1,2,3,4,5,6,7,8,9,0';を試してください。 ShowText(TStringList(GetThis(Free)));ついに無料。終わり;

またはクラスヘルパー:

type TObjectHelper = class helper TObjectプライベート関数の場合はGetThis:TObject;列をなして;パブリックプロパティThis:TObject read GetThis;終わり;

...

function TObjectHelper.GetThis:TObject;開始結果:=自己。終わり;

しかし、実際には、以前の返事は正しいです。「with」文については忘れてください。


12


将来の変更があなたが意図した以上にその範囲に多くを導入するかもしれないので、また決して `with`を使うべきではありません。

例えばこれを取ります。

procedure Test;
var
    x: Integer;
begin
    with TSomeObject.Create do
    begin
        DoSomethingWithX(x);
        Free;
    end;
end;

それから後でTSomeObjectクラスのXプロパティを使います。 さて、どのXを使うと思いますか? オブジェクトのローカル変数またはXプロパティ

最善の解決策は、常に短い名前のローカル変数を作成し、オブジェクトをその変数にエイリアスすることです。

procedure Test;
var
    x: Integer;
    o: TSomeObject;
begin
    o := TSomeObject.Create;
    o.DoSomethingWithX(x);
    o.Free;
end;


3


あなたは答えを自分で与えた:ローカル変数を宣言する。 あなたが欲しいなら、あなたはそれに* with *キーワードを使うことができます。

var MyInstance:TMyObject; MyInstance:= TMyObject.Createを開始します。 MyInstanceでFooを試してみてください。バー; DoSomething(MyInstance);ついに無料。終わり;終わり;

上記の例で* with を使用する唯一の理由はコードの読みやすさであり、これは非常に主観的なので、 with *キーワードを省略してMyInstanceを直接使用することもできます。 それは個人的な好みの問題です。 私は「決して使わない」という答えには同意しませんが、それが欠点であることを知っておくべきです。

この質問も参照してください。https://stackoverflow.com/questions/514482/is-delphi-with-keyword-a-bad-practice


2


Notifyハンドラに関するBrianの例に追加したものは、絶対変数を使用することです(win32のみ)。

手順通知(送信者:TObject); var Something:TSomeThingの絶対送信者。 SenderがTSomethingの場合は開始し、次にVerySimpleProperty:= Something.Something;を開始します。 OtherProperty:= Something.SomethingElse;終わり;終わり;

基本的には、ローカル変数を代入したり、型キャストをたくさんする必要がなくなります。


1


私は難しい方法を学びました - 次のシナリオでは 'With’だけを使ってください。

TMyForm.Create(Owner)を使用して、ShowModalをやっとFreeにします。終わり;

手順通知(送信者:TObject); TSomethingとしてSenderを使用して開始VerySimpleProperty:=何か終了しました。

つまりWithの可視性をできるだけ単純にしてください。 デバッガが 'With’を解決できないという事実を考慮に入れると、単純なローカル変数を使用するか、ターゲットを完全に宣言すること、つまりMyRecord.Somethingを使用することが実際上より明確で明確になります。


0


これは現在不可能ですが、コンパイラの作成者を説得することで実現できます。

TForm1.Create(Nil)を使用する場合// //新しいTForm1インスタンスを使用してみてくださいLogForm( "); //外部メソッドへのパラメータと同じインスタンス(ソリューション)" ShowModal; // Instance.ShowModal最後に "Free; // Instance.Free End;

私の提案は:

  1. Withヘッダーあたり1つのオブジェクト/レコードを超えないでください。

  2. 入れ子のWithsは許可されていません。

  3. オブジェクト/レコードを示すための "の使用法(二重引用符は、同じマーク:http://en.wikipedia.org/wiki/Ditto_markに似ています)。


0


そうするために働く細かいハックがあります。 この回避策をプロジェクト単位で定義してください。

// use variable inside 'with ... do'
// WSelf function returns TObject associated with its method.
//   I would recommend to use the method 'Free'
// WSelf(Free) as
型TObjectMethod =オブジェクトの手続き。 function WSelf(const MethodPointer:TObjectMethod):TObject;開始結果:= TMethod(MethodPointer).Data;終わり;

使用例

var SL:TStringList。 SL:= TStringList.Createを開始します。 TStringListを試してみてください。Add( '1')を試してください。追加( '2');追加( '3'); //(TStringListとしてのWSelf(Free))// TStringList.Create SLによって作成されたオブジェクトへの参照// TStringListとしてのWSelf(Free);ついに無料。終わり;最後にShowMessage(SL.Text); SL無料終わり;終わり;


0


FMXの場合は、GetObjectの例を使用してください。

TLabel.Create(box1)ではFont.Size:= 34を開始します。 Font.Style:= [TFontStyle.fsBold]; TextAlign:= TTextAlign.taCenter; box1.AddObject(GetObject);終わり;;


-1


Delphiで最も良い方法は、そのインスタンスを処理するために変数を使うことです。