Anonymous Methods and Delegates
From The Oxygene Language Wiki
This is a Language topic
Feel free to add your notes to this topic below.
Anonymous methods and delegates are extremely powerful features in Delphi Prism, 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. Without anonymous methods, the application looks like this:
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 delegates 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, just 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 a "normal" method, 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 example 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. (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 an (anonymous) method. In our example 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, Delphi Prism will try to create 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, but 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. Note that any change to the I in the outside scope (the method) will influence the value of I inside the anonymous, so anonymous methods that aren't called till later might have unexpected values if the parent scope changes the variable later on.
Pros and Contras
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", although it is executed in a different thread. You don't have to contaminate your code with hundreds of mini methods and dozens of different delegates, which also improves your productivity.
But use this feature wisely: Having to declare methods and having an interface section is what makes pascal code readable. If you use too many anonymous methods and delegates, your code will be less readable.
Area: Oxygene Language
Compiler version: Oxygene 5
Language Glossary — Keywords — Types — FAQ — How To