try..finally wizard

The try..finally wizard inserts a try .. finally" statement and inserts the code for the finally block based on preceding code. The wizard can be applied on existing code in which case the selection (or line) is moved into the try block, similar to surround with template.

Check the demo movie Code Explorer templates demo movie

C# Example: adding BeginUpdate / EndUpdate

Assume you are filling a list box with strings like this:

public void FillListBox(ListBox listBox)
{
  listBox.Items.Clear();
  for (int index = 1; index <= 1000; index++)
  {
    listBox.Items.Add("Item " + index.ToString());
  }
}

Then you remember you need to use the ListBox.BeginUpdate/EndUpdate methods to avoid flicker. This is a typical case for the try..finally wizard.

Type the code preceding the try statement: "listBox.BeginUpdate();". Then select the code that should be inside the try..finally statement:

public void FillListBox(ListBox listBox)
{
  listBox.BeginUpdate(); // type this line,
  listBox.Items.Clear(); // and select the lines from here..
  for (int index = 1; index <= 1000; index++)
  {
    listBox.Items.Add("Item " + index.ToString());
  } // .. up to here
}

And press Ctrl+Alt+J to invoke the wizard: Refactor

public void FillListBox(ListBox listBox)
{
  listBox.BeginUpdate();
  try
  { Refactor Result
    listBox.Items.Clear();
    for (int index = 1; index <= 1000; index++)
    {
      listBox.Items.Add("Item " + index.ToString());
    }
  }
  finally
  {
    listBox.EndUpdate();Refactor Result
  }
}

As you see: the wizard inserted a try finally statement, detected a BeginUpdate and completed that with a matching call to EndUpdate.

Pascal Example: try..finally Free

In a similar Pascal Win32 example, you could deceide use a TStringList buffer, fill that instead of the listbox and then assign it at once the list box.Items. The first thing to do would be to create the buffer stringlist which itself is a typical case for the "add local var" refactoring.

procedure FillListBox(ListBox: TListBox);
var
  I: Integer;
begin
  Buffer := TStringList.Create;// type this code
  for I := 1 to 1000 do // and select the lines from here...
    ListBox.Items.Add(IntToStr(I)); // ...up to here
end;

After pressing Ctrl+Alt+J to invoke the wizard: Refactor

procedure FillListBox(ListBox: TListBox);
var
  I: Integer;
begin
  Buffer := TStringList.Create;
  try
    for I := 1 to 1000 do
      ListBox.Items.Add(IntToStr(I));
  finally
    Buffer.Free; Refactor Result
  end;
end;

As you see: again the wizard inserted try finally statement and this time detected that the Buffer should be free'd. Of course you'd still need to change the code to fill the buffer rather than the listbox etc. but that's another story.

Example 3 : try..finally Free on new code

This would of course also have worked in the following situation:

procedure FillListBox(ListBox: TListBox);
begin
  Buffer := TStringList.Create;
  // press Ctrl+Alt+J here
end;

Were the wizard would insert this: Refactor

procedure FillListBox(ListBox: TListBox);
begin
  Buffer := TStringList.Create;
  try

  finally
    Buffer.Free; Refactor Result
  end;
end;

Customizing the wizard

The wizard is customizable using a look-up list in file TryFinallyWizard.txt in the shared directory, for example "C:\Program Files\ModelMakerTools\Shared". Here you define word substitution pairs. Substitution pairs are checked in order of appearance if occuring on whole word bounderies. if nothing is substituted, the code to free an object is inserted.

Note: For C# only substitution is done, no object free-ing.