Anonymous Methods and Delegates (Writing)

From RemObjects Software

Jump to: navigation, search

This is a Oxygene Language Feature topic
Feel free to add your notes to this topic below.


Contents

Anonymous Methods and Delegates

Both Anonymous methods and delegates are extremely powerful features in Oxygene, that can not only spare you a lot of time and lines of code, but can make your code much more readable, especially when working with threads that have to access the GUI.

The basics for both anonymous methods and delegates will be explained with an example application: A WPF application that will fill a listbox with numbers using an asynchronous method. First the whole thing without any anonymous things:


Sample without any anonymous things

The asynchronous method uses the .NET Dispatcher class to invoke a method in the GUI's thread. This method matches the signature of delegate defined only for this purpose.

type
  AddToListBox = public method(nr : Integer);

method Window1.DoAddToListBox(nr : Integer);
begin
  numbersListBox.Items.Add(nr);
end;

method Window1.GetNumbers; //declared as async in the interface
begin
  for i : Integer := 0 to Integer.MaxValue do
    Dispatcher.Invoke(DispatcherPriority.ApplicationIdle, new AddToListBox(@DoAddToListBox), i);
end;

Now we have a delegate and a method only to add some numbers to a listbox!

Anonymous Methods

Anonymous methods are methods, that are implemented inside the code of another method by the programmer. The compiler will, of course, create an "normal" method from it, but the programmer won't have to declare a method in the interface or give it a name. That's why they're called "anonymous" methods. In our sample code it looks like this:

type
  AddToListBox = public method(nr : Integer);

method Window1.GetNumbers; //declared as async in the interface
begin
  var aMethod : AddToListBox := method(nr : Integer);
    begin
      numbersListBox.Items.Add(nr);
    end;

  for i : Integer := 0 to Integer.MaxValue do
    Dispatcher.Invoke(DispatcherPriority.ApplicationIdle, aMethod, i);
end;

Now, we don't have to declare an extra method, the compiler is doing that for us. (In truth it creates a whole new class containing that method and holding a reference to our Window1 class.)

Anonymous Delegates

Anonymous delegates make it possible to let the compiler declare a delegate with a signature matching a (anonymous) method. You don't have to care about that, anymore. In our sample code it looks like this:

method Window1.GetNumbers;  //declared as async in the interface
begin
  for i : Integer := 0 to Integer.MaxValue do
    Dispatcher.Invoke(DispatcherPriority.ApplicationIdle, method(nr : Integer); begin
      numbersListBox.Items.Add(nr);
    end, i);
end;

That's all. No delegate, no method in the interface section. Again, the new class is created with a method matching this signature.

Anonymous methods without parameters

When omitting the parameter declaration for an anonymous method declaration, Oxygene will try to make a matching method declaration that fits into the delegate given, but the parameters won't be accessible from inside the method.

if(Self.InvokeRequired) then begin
    Invoke(
      method
      begin
        //...
      end
    );

Using local variables in anonymous methods

Currently we pass the variable i as parameter to our anonymous method. That's not necessary: we can just use the local variable i in the anonymous method and omit the parameter:

method Window1.GetNumbers;  //declared as async in the interface
begin
  for i : Integer := 0 to Integer.MaxValue do
    Dispatcher.Invoke(DispatcherPriority.ApplicationIdle, method; begin
      numbersListBox.Items.Add(i);
    end);
end;

Now the compiler-created class with "our" method is extended by a field containing the value of our local variable i, so that the anonymous method can access it.


Pros and Contras

Well, I think the benefits when using anonymous methods and delegates are obvious: Especially when using them to access different threads, they make it possible to write code, that looks almost as if it was executed "normally", but in truth is executed in a different thread. You don't have to contaminate your code with hundreds of mini methods and dozens of different delegates. It improves your productivity when you don't have to declare method all the time.

But you should use this feature wisely: Having to declare methods and having an interface section is, what makes pascal codes very readable. So you should really think about it, before using anonymous methods and delegates, otherwise you don't get code that is more but less readable.


See also: Anonymous Methods and Delegates


Product: RemObjects Oxygene (formerly known as Chrome)
Current version: 3.0 Previous Versions: 'Joyride' (2.0), 'Floorshow' (1.5), 'Adrenochrome' (1.0)

GlossaryKeywordsLanguage FeaturesPlatform FeaturesSamplesArticlesHow ToIssues

Personal tools