Anonymous Methods and Delegates (Writing)
From RemObjects Software
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)
Glossary — Keywords — Language Features — Platform Features — Samples — Articles — How To — Issues
Categories: Text | Oxygene | Feature
