Reference object instance created using “with” in Delphi

后端 未结 9 1336
生来不讨喜
生来不讨喜 2020-12-03 18:17

is there a way to reference an object instance that is created using the \"with\" statement?

Example:

with TAnObject.Create do
begin
  DoSomething(in         


        
相关标签:
9条回答
  • 2020-12-03 19:00

    This is not possible now, but we can make it a reality by persuading the compiler creators:

      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;
    

    My proposal is:

    1. No more than one object/record per With header.
    2. Nested Withs not allowed.
    3. Usage of " to indicate the object/record (double quotes are similar to the ditto mark: http://en.wikipedia.org/wiki/Ditto_mark).
    0 讨论(0)
  • 2020-12-03 19:01

    Well, you can use such approach:

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

    or class helpers:

    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;
    

    But, actually, previous replies are correct: you should better forget about "with" statement.

    0 讨论(0)
  • 2020-12-03 19:10

    I've learnt the hard way - only use 'With' in the following scenarios:

    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 keep the visibility of With as simple as possible. When you take into account the fact that the debugger cant resolve 'With', it's actually better and clearer to use a simple local variable or to fully declare the target i.e MyRecord.Something

    0 讨论(0)
  • 2020-12-03 19:10

    There is a working fine hack to do so. Define this workaround function somwhere in project unit.

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

    Usage example.

    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;
    
    0 讨论(0)
  • 2020-12-03 19:14

    You gave the answer yourself: declare local variable. If you want you can use the with keyword on that.

    var
      MyInstance: TMyObject;
    begin
      MyInstance := TMyObject.Create;
      with MyInstance do
      try
        Foo;
        Bar;
        DoSomething(MyInstance);
      finally
        Free;
      end;
    end;
    

    In above example the only reason to use with is code readability, which is very subjective, you could also ditch the with keyword and use MyInstance directly. It's just a matter of personal taste. I don't agree on the "never use with" answers, but you should be aware of it's drawbacks.

    See also this question: Is delphi "with" keyword a bad practice?

    0 讨论(0)
  • 2020-12-03 19:14

    The best aproach in Delphi is use a variable to handle that instance.

    0 讨论(0)
提交回复
热议问题