有没有办法引用使用“with”语句创建的对象实例?
例子:
with TAnObject.Create do
begin
DoSomething(instance);
end;
DoSomething 将使用实例引用,就好像您将实例从声明的变量引用传递给创建的对象一样。
例子:
AnObject := TAnObject.Create;
谢谢。
有没有办法引用使用“with”语句创建的对象实例?
例子:
with TAnObject.Create do
begin
DoSomething(instance);
end;
DoSomething 将使用实例引用,就好像您将实例从声明的变量引用传递给创建的对象一样。
例子:
AnObject := TAnObject.Create;
谢谢。
好吧,你可以使用这样的方法:
// implement:
type
TSimpleMethod = procedure of object;
function GetThis(const pr: TSimpleMethod): TObject;
begin
Result := TMethod(pr).Data;
end;
// usage:
with TStringList.Create do
try
CommaText := '1,2,3,4,5,6,7,8,9,0';
ShowText(TStringList(GetThis(Free)));
finally
Free;
end;
或类助手:
type
TObjectHelper = class helper For TObject
private
function GetThis: TObject; Inline;
public
property This: TObject read GetThis;
end;
...
function TObjectHelper.GetThis: TObject;
begin
Result := Self;
end;
但是,实际上,以前的回答是正确的:您最好忘记“with”语句。
您永远不应该使用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;
您自己给出了答案:声明局部变量。如果你愿意,你可以使用with关键字。
var
MyInstance: TMyObject;
begin
MyInstance := TMyObject.Create;
with MyInstance do
try
Foo;
Bar;
DoSomething(MyInstance);
finally
Free;
end;
end;
在上面的示例中,使用with的唯一原因是代码可读性,这是非常主观的,您也可以放弃with关键字并直接使用 MyInstance。这只是个人品味的问题。我不同意“从不使用”的答案,但你应该知道它的缺点。
另请参阅此问题:delphi "with" 关键字是一种不好的做法吗?
Brian 的 Notify 处理程序示例的补充是使用绝对变量(仅限 win32):
procedure Notify( Sender : TObject );
var
Something : TSomeThing absolute Sender;
begin
if Sender is TSomething then
begin
VerySimpleProperty := Something.Something;
OtherProperty := Something.SomethingElse;
end;
end;
它基本上避免了必须分配局部变量或进行大量类型转换。
我已经学会了艰难的方式 - 仅在以下情况下使用“With”:
With TMyForm.Create( Owner ) do
try
ShowModal
finally
Free;
end;
procedure Notify( Sender : TObject );
begin
With Sender as TSomething do
VerySimpleProperty := Something
end;
即尽可能简单地保持 With 的可见性。当您考虑到调试器无法解析“With”这一事实时,使用简单的局部变量或完全声明目标(即 MyRecord.Something)实际上会更好更清晰
现在这是不可能的,但我们可以通过说服编译器创建者来实现:
With TForm1.Create (Nil) Do // New TForm1 instance
Try
LogForm ("); // That same instance as parameter to an outer method (solution)
"ShowModal; // Instance.ShowModal
Finally
"Free; // Instance.Free
End;
我的建议是:
对于 FMX,您应该使用 GetObject 示例:
with TLabel.Create(box1) do
begin
Font.Size := 34;
Font.Style := [TFontStyle.fsBold];
TextAlign := TTextAlign.taCenter;
box1.AddObject(GetObject);
end;;
有一个很好的技巧可以做到这一点。在项目单元中的某处定义此解决方法功能。
// use variable inside 'with ... do'
// WSelf function returns TObject associated with its method.
// I would recommend to use the method 'Free'
// WSelf(Free) as <TObjectN>
type TObjectMethod = procedure of object;
function WSelf(const MethodPointer: TObjectMethod): TObject;
begin
Result := TMethod(MethodPointer).Data;
end;
用法示例。
var
SL: TStringList;
begin
SL := TStringList.Create;
try
with TStringList.Create do
try
Add('1');
Add('2');
Add('3');
// (WSelf(Free) as TStringList) references to the object
// created by TStringList.Create
SL.Assign(WSelf(Free) as TStringList);
finally
Free;
end;
finally
ShowMessage(SL.Text);
SL.Free;
end;
end;
Delphi 中最好的方法是使用变量来处理该实例。