Delphi 使用“引用”创建的引用对象实例;加上;在德尔菲

Delphi 使用“引用”创建的引用对象实例;加上;在德尔菲,delphi,with-statement,Delphi,With Statement,是否有方法引用使用“with”语句创建的对象实例 例如: with TAnObject.Create do begin DoSomething(instance); end; AnObject := TAnObject.Create; 其中,DoSomething将使用实例引用,就好像您正在将一个实例从声明的变量引用传递到创建的对象一样 例如: with TAnObject.Create do begin DoSomething(instance); end; AnObject :

是否有方法引用使用“with”语句创建的对象实例

例如:

with TAnObject.Create do
begin
  DoSomething(instance);
end;
AnObject := TAnObject.Create;
其中,DoSomething将使用实例引用,就好像您正在将一个实例从声明的变量引用传递到创建的对象一样

例如:

with TAnObject.Create do
begin
  DoSomething(instance);
end;
AnObject := TAnObject.Create;

谢谢。

您也不应该将
一起使用,因为将来的更改可能会超出您的预期范围

以此为例:

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;

那么,你可以使用这样的方法:

// 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”:

With TMyForm.Create( Owner ) do
  try
    ShowModal
  finally
    Free;
  end;


procedure Notify( Sender : TObject );
begin
  With Sender as TSomething do
    VerySimpleProperty := Something      
end;

i、 e使用尽可能简单的方法保持图像的可见性。当您考虑到调试器无法解析“With”时,使用简单的局部变量或完全声明目标(即MyRecord)实际上更好、更清晰。您自己给出了答案:声明局部变量。如果需要,您可以在上面使用with关键字

var
  MyInstance: TMyObject;
begin
  MyInstance := TMyObject.Create;
  with MyInstance do
  try
    Foo;
    Bar;
    DoSomething(MyInstance);
  finally
    Free;
  end;
end;
在上面的示例中,使用with的唯一原因是代码可读性,这是非常主观的,您也可以放弃with关键字,直接使用MyInstance。这只是个人品味的问题。我不同意“从不与一起使用”的答案,但你应该意识到它的缺点


另请参见此问题:

Brian关于Notify处理程序的示例的一个补充是使用绝对变量(仅限win32):


它基本上避免了必须分配局部变量或进行大量类型转换。

这现在不可能,但我们可以说服编译器创建者:

  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;
我的建议是:

  • 每个具有标题的对象/记录不超过一个
  • 不允许嵌套
  • 使用“表示对象/记录(双引号类似 同上标记:)

  • 这样做有一个很好的方法。 在项目单元中的何处定义此变通功能

    // 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;
    

    Delphi中最好的方法是使用变量来处理该实例。

    对于FMX,应该使用GetObject 例如:


    +1:)在我最初做Delphi的时候,这些助手的东西都不存在。看到这一点很有趣,因为我上周写了这篇博客文章,计划在下周发布(那时我将忙于完成并准备离开Delphi Live!会议):PS:pitty我看不懂俄语,谷歌俄语->英语翻译在翻译你非常有趣的博客时忘记了很多!Bevare说,删除TObject的助手会破坏TObject的任何现有助手。每个类只能有一个助手。我不喜欢助手…带有语句的助手很有用。它们不是很好的设计公关实践。它们在适用的地方很好地发挥作用。好吧,我要咬一口:-)“with”如果你不小心的话可能会引起严重的混乱,但在某些情况下,它只会使代码更可读。仔细命名在这里会有所帮助。使用命名方案来避免混乱是Delphi代码的一种常见技术(使用TXxx表示类型,使用FXxxx表示私有成员,使用GetXxx和SetXxx表示getter和setter等)。只需使用MyXxx或类似的方法表示局部变量,您就不会像调用变量“x”和“o”那样产生太多的混乱"。我不会用它的自动作用域功能让它更具可读性的少数情况来交换。我已经在与此相关的问题上浪费了数周时间。没有任何代码可以被证明可读性如此之高,以至于花那么多时间来发现奇怪的错误。我同意不使用。但我会建议您请在“创建”之后尝试,在“免费”之前尝试。+1用于向我们介绍“绝对”的使用(很久以前,绝对内存引用引入了绝对内存引用,但您的示例是唯一与.net和原生世界兼容的用法)。我经常使用这种构造,但最近我意识到它会干扰编译器的优化器。因此,如果这很重要,使用这种构造可能会导致代码生成效率低下(但如果速度不重要,IMO可能会导致代码更易于阅读)。
    with TLabel.Create(box1) do
    begin
        Font.Size := 34;
        Font.Style := [TFontStyle.fsBold];
        TextAlign := TTextAlign.taCenter;
        box1.AddObject(GetObject);
    end;;