Lambda expressions in Java

Introduction

If you’re familiar with .NET then you already know what Lambda expressions are and how useful they can be. They were not available in Java before version 8. Let’s investigate how they can be applied in Java.

First example: an interface method with a single parameter

Say you have the following Employee class:

Read more of this post

Lambda expressions in Java

Introduction

If you’re familiar with .NET then you already know what Lambda expressions are and how useful they can be. They were not available in Java before version 8. Let’s investigate how they can be applied in Java.

First example: an interface method with a single parameter

Say you have the following Employee class:

Read more of this post

Lambda expressions in Java 8 part 2: extended syntax and the function package

Introduction

In the previous post in this short series we introduced the syntax of lambda expressions in Java 8. In this post we’ll look at a couple more facets of lambda expressions in Java: the ‘::’ operator and the new java.util.function package.

Syntactic sugar with ‘::’

There’s a new operator in Java 8: ‘::’, i.e. a double-colon. It’s used as a shortcut to write lambda expressions. Recall our Comparator implementation from the previous post:

Comparator<Employee> employeeAgeComparator = 
                (employeeOne, employeeTwo) -> Integer.compare(employeeOne.getAge(), employeeTwo.getAge());

That was an Employee comparison where the input parameters were of type Employee but we compared their ages which are of type Integer. Say that we first collect the age values into a separate integer list. We can then write a pure integer comparator in a very similar way:

Comparator<Integer> intComparator = (int1, int2) -> Integer.compare(int1, int2);

This can be rewritten as follows:

Comparator<Integer> intComparatorShort = Integer::compare;

This way of writing the lambda expression is called a method reference. We first write the object on which we want to invoke a method, i.e. “Integer”, followed by a double-colon, and finally we have the name of the method. The compiler will infer from the Comparator type that we want to compare two integers so we don’t need to write compare(int1, int2). We’ll see other examples of this later on but the difference between this syntax and the one we saw in the previous post is purely syntactic. There’s no performance gain or loss with either of them.

java.util.function

Java.util.function is a new package that provides a range of functional interfaces. If you work in an IDE which provides intellisense – such as NetBeans – then you can type “import java.util.function.” above a class declaration to see the list of interfaces within this package. You’ll see names such as…

BiConsumer<T, U>
Consumer<T>
LongSupplier

At first these interfaces probably look quite strange. They are out-of-the box functional interfaces that represent some frequently used methods so that they can be written as lambda expressions. Examples:

  • BiConsumer of T and U: represents a void method that accepts two arguments of types T and U
  • Consumer of T: same as BiConsumer but it accepts a single parameter only
  • IntSupplier: a method that returns an integer and accepts no arguments
  • BiPredicate of T and U: a function that returns a boolean and accepts two arguments
  • Function of T and R: a function that accepts an argument of type T and returns and object of type R

The input and output parameter types can be the same or different.

There are also specialised interfaces such as the UnaryOperator of T which extends Function of T and T. This means that UnaryOperator is a Function which returns an object of type T and returns an object of type T, i.e. both the input and output parameters are of the same type.

A simple example is System.out.println(String s). This is a void method that accepts a single argument of String, i.e. this fits the functional interface type of Consumer of String:

Consumer<String> systemPrint = s -> System.out.println(s);

We know from the above section that we can shorten this code to the following:

Consumer<String> systemPrint = System.out::println;

The Comparator of integers we saw above accepts two integers and returns another integer. This sounds like a BiFunction of int, int, int, i.e. a function that accepts 2 integers and returns another integer:

BiFunction<Integer, Integer, Integer> intComparatorFunctional = (t, t1) -> Integer.compare(t, t1);

…and as all types are the same we can use the shorthand notation:

BiFunction<Integer, Integer, Integer> intComparatorFunctional = Integer::compare;

We can further simplify this as there’s a specialised functional interface for the case of two integer inputs and one integer return value: IntBinaryOperator. The shortened version of the integer comparator looks like this:

IntBinaryOperator intComparatorAsBinaryOperator = Integer::compare;

So if you see that all parameters are of the same type then it’s worth checking what’s available in the java.util.function package because there might be a specialised interface. Choose the one that you think is most straightforward.

You can use these interfaces to pass around lambda expressions as input parameters. E.g. there’s a new method available for Collections, or objects that implement the Iterable interface to be exact: forEach, which accepts a Consumer of T. In other words you can iterate through the items in a collection and pass in a Consumer, i.e. a void method which accepts a single parameter to perform some action on each item in a collection in a single statement:

stringList.forEach(s -> System.out.println(s));

…or…:

stringList.forEach(System.out::println);

Other examples:

Add the items of a list to Employee objects to another list – we saw the Employee object in the previous post:

List<Employee> employees = new ArrayList<>();
        List<Employee> employeesCopy = new ArrayList<>();
        employees.add(new Employee(UUID.randomUUID(), "Elvis", 50));
        employees.add(new Employee(UUID.randomUUID(), "Marylin", 18));
        employees.add(new Employee(UUID.randomUUID(), "Freddie", 25));
        employees.add(new Employee(UUID.randomUUID(), "Mario", 43));
        employees.add(new Employee(UUID.randomUUID(), "John", 35));
        employees.add(new Employee(UUID.randomUUID(), "Julia", 55));        
        employees.add(new Employee(UUID.randomUUID(), "Lotta", 52));
        employees.add(new Employee(UUID.randomUUID(), "Eva", 42));
        employees.add(new Employee(UUID.randomUUID(), "Anna", 20));   
        
        Consumer<Employee> copyEmployees = employeesCopy::add;
        employees.forEach(copyEmployees);

employeesCopy will have the same objects as the employees list.

You can even chain Consumers with the “andThen” interface method:

Consumer<Employee> copyEmployees = employeesCopy::add;
Consumer<Employee> printEmployeeName = (Employee e) -> System.out.println(e.getName());
employees.forEach(copyEmployees.andThen(printEmployeeName));

View all posts related to Java here.

Lambda expressions in Java 8 part 1: basic syntax

Introduction

If you’re familiar with .NET then you already know what Lambda expressions are and how useful they can be. They were not available in Java before version 8. Let’s investigate how they can be applied in Java.

First example: an interface method with a single parameter

Say you have the following Employee class:

public class Employee
{
    private UUID id;
    private String name;
    private int age;

    public Employee(UUID id, String name, int age)
    {
        this.id = id;
        this.name = name;
        this.age = age;
    }
        
    public UUID getId()
    {
        return id;
    }

    public void setId(UUID id)
    {
        this.id = id;
    }

    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name = name;
    }    
    
    public int getAge()
    {
        return age;
    }

    public void setAge(int age)
    {
        this.age = age;
    }
}

You can judge whether or not an Employee is cool based on a number of factors. As the implementation of “coolness” can vary so let’s hide it behind an interface:

public interface EmployeeCoolnessJudger
{
    boolean isCool(Employee employee);
}

Here comes an anonymous implementation of the EmployeeCoolnessJudger interface based on the employee name. We simply say that everyone with the name “Elvis” is cool:

EmployeeCoolnessJudger nameBasedCoolnessJudger = new EmployeeCoolnessJudger()
{
            @Override
            public boolean isCool(Employee employee)
            {
                return employee.getName().equals("Elvis");
            }
};

In Java 8 this can be rewritten as follows:

EmployeeCoolnessJudger nameBasedCoolnessJudgerAsLambda = 
                (Employee employee) -> employee.getName().equals("Elvis");

If you know lambdas from .NET then this will look very familiar to you. We declare the input parameters within brackets to the isCool method. As the interface has only one method it’s not necessary to show its name anywhere, the compiler will “understand”. The parameter declaration is followed by a dash ‘-‘ and the greater-than sign, which is similar to ‘=>’ in .NET. Then we write what we want the function to return which will be a boolean. Note that we don’t need the return statement. Also, as the whole method implementation fits into a single line we didn’t need any curly braces.

The parameter type can in fact be omitted, which is again similar to .NET:

EmployeeCoolnessJudger nameBasedCoolnessJudgerAsLambda = 
                (employee) -> employee.getName().equals("Elvis");

…and if there’s only one parameter then the brackets can be omitted as well:

EmployeeCoolnessJudger nameBasedCoolnessJudgerAsLambda = 
                employee -> employee.getName().equals("Elvis");

How can we use this lambda implementation of EmployeeCoolnessJudger? You can pass it around like any other object. Say the Employee class has a function that accepts an EmployeeCoolnessJudger:

public boolean isCool(EmployeeCoolnessJudger coolnessJudger)
{
     return coolnessJudger.isCool(this);
}

Then you can construct an Employee object and pass the lambda expression name into the isCool method:

Employee coolEmployee = new Employee(UUID.randomUUID(), "Elvis", 50);
boolean isCool = coolEmployee.isCool(nameBasedCoolnessJudgerAsLambda);

…or you can pass the complete Lambda expression into the function…:

Employee coolEmployee = new Employee(UUID.randomUUID(), "Elvis", 50);
boolean isCool = coolEmployee.isCool(employee -> employee.getName().equals("Elvis"));

…which returns true as expected.

Second example: an interface with no parameters

The above example required a single parameter. How is the syntax affected if there are no parameters? Say that we want an employee to say something. Again, we can hide the implementation behind an interface:

public interface EmployeeSpeaker
{
    void speak();
}

We can implement an anonymous method of this to say “Hello World”:

EmployeeSpeaker helloWorldSpeaker = new EmployeeSpeaker()
{

            @Override
            public void speak()
            {
                System.out.println("I'm saying Hello World!");
            }
};

The anonymous helloWorldSpeaker implementation can be rewritten with a Lambda expression as follows:

EmployeeSpeaker helloWorldSpeaker = () ->  System.out.println("I'm saying Hello World!");

As the implementation doesn’t require any input parameters it’s enough to write empty brackets followed by dash and greater-than. If the method body spans more than one line of code we’ll need to put them within curly braces:

EmployeeSpeaker helloWorldSpeaker = () ->
        { 
            String sentence = "I'm saying Hello World!";
            System.out.println(sentence);        
        };

The usage is the same as above. The employee class can have a method that accepts an EmployeeSpeaker as input parameter:

public void saySomething(EmployeeSpeaker speaker)
    {
        speaker.speak();
    }

You can call it as follows:

coolEmployee.saySomething(helloWorldSpeaker);

…which will print “I’m saying Hello World!” to some console depending on the IDE you’re using.

Third example: an interface with 2 or more parameters

We want to compare the Employee objects based on their ages and sort them accordingly. One way to achieve this is to implement the generic Comparator interface. Say we have the following employees:

List<Employee> employees = new ArrayList<>();
        employees.add(new Employee(UUID.randomUUID(), "Elvis", 50));
        employees.add(new Employee(UUID.randomUUID(), "Marylin", 18));
        employees.add(new Employee(UUID.randomUUID(), "Freddie", 25));
        employees.add(new Employee(UUID.randomUUID(), "Mario", 43));
        employees.add(new Employee(UUID.randomUUID(), "John", 35));
        employees.add(new Employee(UUID.randomUUID(), "Julia", 55));        
        employees.add(new Employee(UUID.randomUUID(), "Lotta", 52));
        employees.add(new Employee(UUID.randomUUID(), "Eva", 42));
        employees.add(new Employee(UUID.randomUUID(), "Anna", 20));   

Here comes the anonymous class solution to implement Comparator of Employee:

Comparator<Employee> employeeAgeComparator = new Comparator<Employee>()
        {

            @Override
            public int compare(Employee employeeOne, Employee employeeTwo)
            {
                return Integer.compare(employeeOne.getAge(), employeeTwo.getAge());
            }
        };

…and here comes the lambda solution. Note that we have 2 input parameters:

Comparator<Employee> employeeAgeComparator = 
      (Employee employeeOne, Employee employeeTwo) -> Integer.compare(employeeOne.getAge(), employeeTwo.getAge());

…or without specifying the parameter types:

Comparator<Employee> employeeAgeComparator = 
                (employeeOne, employeeTwo) -> Integer.compare(employeeOne.getAge(), employeeTwo.getAge());

As we have more than one input parameters we cannot leave off the brackets.

We can use the custom comparator as follows:

Collections.sort(employees, employeeAgeComparator);
        
for (Employee employee : employees)
{
       System.out.println(employee.getName());
}

This prints out the names as follows:

Marylin
Anna
Freddie
John
Eva
Mario
Elvis
Lotta
Julia

Some things to note

Lambdas in Java also introduced a couple of new concepts::

  • The type definition of a Lambda expression is functional interface. Such an interface type can only have one abstract method.
  • You can use the @FunctionalInterface annotation to annotate functional interfaces if you prefer to be explicit about it, see example below
  • Lambda expressions can be used as variables and passed into other methods. We’ve seen examples of that above: nameBasedCoolnessJudgerAsLambda and employeeAgeComparator. As a consequence a Lambda expression can be returned by a method as well. E.g. nameBasedCoolnessJudger can be returned from a method whose return type is EmployeeCoolnessJudger
  • Creating Lambdas doesn’t involve as much overhead as creating an anonymous object with the “new” keyword so you can speed up the application by lambdas.

Here’s an example of the FunctionalInterface annotation:

@FunctionalInterface
public interface ISomeFunctionalInterface
{
    void doSomething(String param);
}

As soon as you try to add another abstract method to this interface you’ll get a compiler error:

@FunctionalInterface
public interface ISomeFunctionalInterface
{
    void doSomething(String param);
    int returnSomething();
}

…:

error: Unexpected @FunctionalInterface annotation
@FunctionalInterface
ISomeFunctionalInterface is not a functional interface
multiple non-overriding abstract methods found in interface ISomeFunctionalInterface

We’ll continue with terminal and intermediary operations in the next post.

View all posts related to Java here.

Events, delegates and lambdas in .NET C# part 6: other scenarios

Introduction

So far in this series we’ve seen the basics of events, delegates and lambdas. We’ve looked at examples of how to define these elements and use them in code.

It’s now time for us to look at some other simulated scenarios where you can use these language elements. In particular we’ll look at the following:

  • Mediator pattern with delegates
  • Asynchronous delegate invocation

Communication across components

Imagine a scenario where you have a dynamic GUI of a Windows application. The components – widgets – can be loaded here and there and they are independent of each other to allow for loose coupling. At the same time they should be able to communicate with each other.

This scenario can be generalised: imagine independent objects that don’t know about other objects but still want to communicate with them in case they are present.

This is a perfect scenario for events and delegates and a pattern called the Mediator pattern. If you don’t know what a mediator is then make sure to read that introduction where the pattern is demonstrated without using events and delegates. With independent components we’ll need a Mediator that acts as a glue for those components. They will only know about the Mediator but not the other objects they are indirectly communicating with.

An additional pattern that is useful in this scenario is the Singleton pattern. If you don’t know what it means then skim through that article to get the basics. The purpose of the singleton in this case is to have only one Mediator class in memory. Otherwise the independent components may reference different mediators.

Note that this post concentrates on the role of delegates and events. If you’d like to extend this example so that it better follows SOLID and abstractions then look through blog entries in the Architecture and patterns section.

Open the project we’ve been working on in this series and add a new C# library called ComponentsMediator. Add a new class to it called Mediator which will be responsible for the communication between the independent components.

Add the following elements to adhere to the singleton pattern. We’ll employ a simple version of the pattern. Read the referenced article to see what some of the other possible solutions are.

private static readonly Mediator _instance = new Mediator();

private Mediator() { }
public static Mediator Instance
{
        get
	{
		return _instance;
	}
}

We’ll simulate the scenario where the user selects a product in a drop down list. We want to update the screen accordingly. Add the following Product class to the project:

public class Product
{
	public int Id { get; set; }
	public string Name { get; set; }
	public DateTime Registered { get; set; }
	public int OnStock { get; set; }
}

Return to Mediator.cs and add the following event handler to the Mediator:

public event EventHandler<ProductChangedEventArgs> ProductChanged;

…where ProductChangedEventArgs looks as follows:

public class ProductChangedEventArgs : EventArgs
{
	public Product Product { get; set; }
}

We’ll raise the event in the following method:

public void OnProductChanged(object sender, Product product)
{
	if (ProductChanged != null)
	{
		ProductChanged(sender, new ProductChangedEventArgs() { Product = product });
	}
}

By allowing the sender to be passed in we show that the original event raiser was an object different from the Mediator. Otherwise all products would “think” that the Mediator raised the event which is not entirely true. Keep in mind that the mediator is only an errrm…, well, a mediator. It mediates between independent objects. We need to see if there’s any listener by checking if ProductChanged is null.

Let’s add a component that will initiate the product selection change. You can think of this object as a combo box where the users can select products:

public class ProductChangeInitiator
{
	public ProductChangeInitiator(int selectedProductId)
	{
		SelectedProductId = selectedProductId;			
	}

	public int SelectedProductId { get; set; }

}

Add another class to the library called ProductChangeSimulation and a method called SimulateProductChange:

public class ProductChangeSimulation
{
        private List<Product> _allProducts = new List<Product>()
	{
		new Product(){Name = "FirstProduct", Id = 1, Registered = DateTime.Now.AddDays(-1), OnStock = 456}
		, new Product(){Name = "SecondProduct", Id = 2, Registered = DateTime.Now.AddDays(-2), OnStock = 123}
		, new Product(){Name = "ThirdProduct", Id = 3, Registered = DateTime.Now.AddDays(-3), OnStock = 987}
		, new Product(){Name = "FourthProduct", Id = 4, Registered = DateTime.Now.AddDays(-4), OnStock = 432}
		, new Product(){Name = "FifthProduct", Id = 5, Registered = DateTime.Now.AddDays(-5), OnStock = 745}
		, new Product(){Name = "SixthProduct", Id = 6, Registered = DateTime.Now.AddDays(-6), OnStock = 456}
	};

	public void SimulateProductChange(ProductChangeInitiator changeInitiator)
	{
		Product selectedProduct = (from p in _allProducts where p.Id == changeInitiator.SelectedProductId select p).FirstOrDefault();
		Mediator.Instance.OnProductChanged(changeInitiator, selectedProduct);
	}
}

We maintain a list of products in a private variable. We let the product change initiator to be passed into the method. We then call the OnProductChanged event handler of the mediator by passing the changeInitiator as the original sender and the selected product.

We now have the components ready in order to raise the event and pass in the necessary parameters. We’ll now need a listener. Add a new class called Warehouse:

public class Warehouse
{
	public Warehouse()
	{
		Mediator.Instance.ProductChanged += (s, e) => { SaveChangesInRepository(e.Product); };
	}

	private void SaveChangesInRepository(Product product)
	{
		Console.WriteLine("About to save the changes for product {0}", product.Name);
	}
}

We subscribe to the ProductChanged event of the mediator where the initiator of the event is unknown to Warehouse. It could be any component in reality: a customer, an e-commerce site, a physical shop, whatever. The Warehouse object won’t care. It only wants to know if there was a change so that it can go on with its job. As you see we declared the event subscription with a lambda.

Add a reference from the main project to the ComponentsMediator library. We can connect the pieces from Program.Main as follows:

ProductChangeInitiator initiator = new ProductChangeInitiator(2);
Warehouse warehouse = new Warehouse();
ProductChangeSimulation simulation = new ProductChangeSimulation();
simulation.SimulateProductChange(initiator);

We simulate the product id #2 was selected and start the simulation. You’ll see that Warehouse correctly displays the message in the console.

Let’s add another listener to the library project. Let’s say that the company CEO is a control freak and wants to be notified of all product changes:

public class CEO
{
	public CEO()
	{
		Mediator.Instance.ProductChanged += (s, e) => 
		{ 
			Console.WriteLine("This is the CEO speaking. Well done for selling {0}", e.Product.Name); 
		};
	}
}

Extend the code in Main as follows:

ProductChangeInitiator initiator = new ProductChangeInitiator(2);
Warehouse warehouse = new Warehouse();
CEO ceo = new CEO();
ProductChangeSimulation simulation = new ProductChangeSimulation();
simulation.SimulateProductChange(initiator);

You’ll see that the CEO is very happy now. We effortlessly added another listener to the product change. The CEO, Warehouse and ProductChangeInitiator objects don’t know about each other. This ensures that the components remain loosely coupled. The listeners won’t care where the notification is coming from, they are only connected to the mediator.

Asynchronous delegates

Let’s look at how asynchronous operations can be applied to delegates. Insert a new C# library to the project called AsyncDelegates. Insert a new class called AsynchronousProcessSimulation. Imagine that we start a long process and want to be notified of the progress made. Insert the following method that represents our lengthy process:

private void DoProgress(int maxValue)
{
	for (int i = 0; i <= maxValue; i++)
	{
		Console.WriteLine("Time : {0}", i);
		Thread.Sleep(50);
	}
}

We want to use a delegate to wire the information to the DoProgress method. We’ll do it with a private delegate:

private delegate void ShowProgressDelegate(int status);

Insert the following public entry point that initiates the delegate:

public void StartReporting()
{
	ShowProgressDelegate progressDelegate = new ShowProgressDelegate(DoProgress);
}

Let’s say that we want to invoke this delegate asynchronously. Delegates have a built-in method called BeginInvoke which comes in very handy. It will spin up a separate thread that will call into DoProgress. We can pass in the value for the maxValue parameter, a callback function and an additional object input which will be null in this example. We don’t need a callback either. Add the following async call to StartReporting:

progressDelegate.BeginInvoke(500, null, null);
Console.WriteLine("Finishing the StartReporting method.");

Insert a reference to this project from the main project. You can test the async delegate as follows:

AsynchronousProcessSimulation asyncSimulation = new AsynchronousProcessSimulation();
asyncSimulation.StartReporting();

You’ll see that “Finishing the StartReporting method.” is printed in the console after the delegate has been invoked on a different thread proving the point that BeginInvoke did in fact spawn up a new thread. The lengthy operation just keeps running in the background.

This post finishes this series on delegates and events. I hope you have learned some new stuff that you can use in your own project.

Events, delegates and lambdas in .NET C# part 5: lambda, Func, Action

Introduction

In this post we’ll continue our discussion by diving into the following topics:

  • Lambdas
  • Func of T,TResult
  • Action of T

Lambdas

Lambdas fit very well into the topic of events and delegates. We touched upon anonymous methods at the end of the previous post:

superman.WorldSavingCompleted += delegate(object sender, WorldSavingCompletedEventArgs e)
{
	StringBuilder superHeroMessageBuilder = new StringBuilder();
	superHeroMessageBuilder.Append("Superhero has saved the world! Name: ").Append(e.Saviour)
		.Append(", time spent saving the world: ").Append(e.HoursItTookToSaveWorld).Append(", message from the superhero: ")
		.Append(e.MessageFromSaviour);
	Console.WriteLine(superHeroMessageBuilder.ToString());
};

Anonymous methods are a good way to get going with lambdas as they have a similar syntax. However, lambdas are more concise. The following is the lambda equivalent of the anonymous method:

superman.WorldSavingCompleted += (s, e) => 
{
	StringBuilder superHeroMessageBuilder = new StringBuilder();
	superHeroMessageBuilder.Append("Superhero has saved the world! Name: ").Append(e.Saviour)
		.Append(", time spent saving the world: ").Append(e.HoursItTookToSaveWorld).Append(", message from the superhero: ")
		.Append(e.MessageFromSaviour);
	Console.WriteLine(superHeroMessageBuilder.ToString());
};

In case the method body is a single statement then you can leave out the curly braces:

superman.WorldSavingCompleted += (s, e) => Console.WriteLine("World saved by " + e.Saviour);

Note how you can access the properties of the event args without having to declare the exact type in the parameter list.

The structure of a lambda expression is the following:

  • Method parameters, in this case (s, e). If there are no input params then this simply becomes (). The compiler will infer the parameter types from the delegate signature. That’s how you could access the Saviour property of the WorldSavingCompletedEventArgs parameter
  • The parameters are followed by the lambda operator ‘=>’. It separates the input parameters from the method body
  • The method body: the parameters defined within the parenthesis will be passed into this inline method

Lambdas with custom delegates

Open the console application we’ve been working on in this series. Add a new class called ProcessIntegers:

public class ProcessIntegers
{
	public void DoAction(int firstInteger, int secondInteger)
	{
	}
}

At first this doesn’t look very clever: we don’t know how the integers will be processed and the method doesn’t return anything. However, by now we know that with delegates and events we can return multiple values from a void method. The goal here is to generalise the way two integers are handled: multiply them, add them etc. Instead of guessing what a client may want to do with the integers and writing 10 methods we’ll let the client define the operation.

In Program.cs insert the following custom delegate:

public delegate int IntegerOperationDelegate(int first, int second);

So it takes two integers and returns an integer. Let’s extend the DoAction method so that it accepts a delegate of this type:

public void DoAction(int firstInteger, int secondInteger, IntegerOperationDelegate del)
{
	int result = del(firstInteger, secondInteger);
	Console.WriteLine(result);
}

So we invoke the delegate in the method body and print out the result. The method allows the caller to pass in a custom delegate so that the DoAction method doesn’t have to be hard coded as far as processing the two integers are concerned. The DoAction method will have no knowledge about the exact delegate passed in which allows for the construction of loosely coupled classes. You can call DoAction from Main using lambdas. Here’s the first integer processor:

IntegerOperationDelegate addIntegersDelegate = (f, s) => f + s;

Looks weird if you see this for the first time, right? You’ll now recognise the input parameters and the lambda operator. Recall that the signature must match the delegate signature hence the (f, s) bit which stand for the first and second integers. The ‘f + s’ bit looks strange as there’s no return statement. It is added by the compiler for you in case there are no curly braces. It is inferred from the delegate signature that you’d like to add two numbers and return the result. A more obvious way of declaring this delegate is the following:

IntegerOperationDelegate addIntegersDelegate = (f, s) => { return f + s; };

Let’s add a couple more delegates:

IntegerOperationDelegate addSquaresOfIntegersDelegate = (f, s) => (f * f) + (s * s);
IntegerOperationDelegate doSomethingRandomDelegate = (f, s) => (f + 3) * (s + 4);

We can then call DoAction as follows:

ProcessIntegers processIntegers = new ProcessIntegers();
processIntegers.DoAction(4, 5, addSquaresOfIntegersDelegate);
processIntegers.DoAction(4, 5, doSomethingRandomDelegate);

So it’s up to the caller to inject the correct rule on how to process the integers. The DoAction method will happily invoke the delegate without having prior knowledge on what’s going to happen to them.

These were a couple of simple examples on how custom delegates work with lambdas.

In the next sections we’ll see how to work with the delegates built into the .NET framework.

Action of T

Action of T represents a delegate that accepts a single parameter and returns no value. The Action object is of type ‘delegate’. You can pass in any object of type T. With Action of T you can skip declaring your delegate as ‘delegate void NameOfDelegate(params)’. Action of T provides a shorter solution to that as it already encapsulates a delegate. You can declare an Action as follows:

Action<string> actionOfString = MatchingActionOfT;
actionOfString("Test");

…where MatchingActionOfT is a method that takes a string to make sure it matches the delegate signature:

private static void MatchingActionOfT(string inputs)
{
	Console.WriteLine(inputs);
}

What if you need to pass in more parameters? That’s no problem as Action of T has 16 versions ranging from…

Action<in T>

…to

Action<in T1, in T2, ... , in T16>

If 16 separate input parameters are not enough then you need to seriously review your code.

You can even assign built-in methods to the Action if the method signature is correct:

Action<string> consoleString = Console.WriteLine;
consoleString("Test from console.");

Extend the ProcessIntegers class with the following method:

public void DoAction(int firstInteger, int secondInteger, Action<int, int> action)
{
        action(firstInteger, secondInteger);
	Console.WriteLine("Paramaters passed: {0}, {1}", firstInteger, secondInteger);
}

In Main we can declare our action:

Action<int, int> voidAction = (f, s) => Console.WriteLine(f + s);

…and then invoke it indirectly:

ProcessIntegers processIntegers = new ProcessIntegers();
processIntegers.DoAction(2, 2, voidAction);

The overloaded DoAction method will invoke the voidAction Action for us which will result in a printout on the console window.

Function of T, TResult

This is similar to Action of T. Its type is still ‘delegate’. The key difference is that it has a return value of type TResult. Just like with Actions you can pass in 16 parameters. The return type is always the last element in the type declaration. A function that takes two integers and returns a double will look like this:

Func<int, int, double> func = MatchingFuncOfT;

…and a matching method will take the following form:

private double MatchingFuncOfT(int first, int second)
{
	return first / second;
}

The Func delegate can be invoked as usual:

double res = func(3, 2);

In case the Func doesn’t accept any parameters then the single type declaration will be the return type:

Func<out T>

Just like with Action of T this method saves you the time and code declaring the custom delegate.

Previously in this post we added a custom delegate and created instances of that delegate using lambdas:

IntegerOperationDelegate addIntegersDelegate = (f, s) => f + s;
IntegerOperationDelegate addSquaresOfIntegersDelegate = (f, s) => (f * f) + (s * s);
IntegerOperationDelegate doSomethingRandomDelegate = (f, s) => (f + 3) * (s + 4);

We can achieve the same goal as follows:

Func<int, int, int> addIntegersFunction = (f, s) => f + s;
Func<int, int, int> addSquaresOfIntegersFunction = (f, s) => (f * f) + (s * s);
Func<int, int, int> doSomethingRandomFunction = (f, s) => (f + 3) * (s + 4);

Insert the following method into ProcessIntegers:

public void DoAction(int firstInteger, int secondInteger, Func<int, int, int> action)
{
	int res = action(firstInteger, secondInteger);
	Console.WriteLine("Func result: {0}", res);
}

We invoke the action in the usual way of invoking methods. We get the result and print it on the Console. Just like before, the DoAction method is not aware of what’s going on within the action.

We can call the overloaded DoAction method from Main as follows:

processIntegers.DoAction(2, 2, addIntegersFunction);
processIntegers.DoAction(4, 5, addSquaresOfIntegersFunction);
processIntegers.DoAction(4, 5, doSomethingRandomFunction);

Lambdas and Funcs in LINQ

Lambdas and Funcs are often used in LINQ when querying objects. Add a Product object to the solution:

public class Product
{
	public int Id { get; set; }
	public string Name { get; set; }
	public string Description { get; set; }
	public int OnStock { get; set; }
}

Add a ProductService with a list of all products and a method stub:

public class ProductService
{
	private List<Product> _allProducts = new List<Product>()
	{
		new Product(){Description = "FirstProduct", Id = 1, Name = "FP", OnStock = 456}
		, new Product(){Description = "SecondProduct", Id = 2, Name = "SP", OnStock = 123}
		, new Product(){Description = "ThirdProduct", Id = 3, Name = "TP", OnStock = 987}
		, new Product(){Description = "FourthProduct", Id = 4, Name = "FoP", OnStock = 432}
		, new Product(){Description = "FifthProduct", Id = 5, Name = "FiP", OnStock = 745}
		, new Product(){Description = "SixthProduct", Id = 6, Name = "SiP", OnStock = 456}
	};

	public void PlayWithLinq()
	{
	}
}

Start typing the following statement in PlayWithLinq:

IEnumerable<Product> filteredProducts = _allProducts.Where(

As you type ‘(‘ IntelliSense will show that Where accepts a Function of Product that returns a boolean. This means that the function will look at the Product objects in _allProducts and if there’s a match, i.e. the Func returns true, then the Product will be added to the List of products. Now that we know lambdas we can have something like this:

IEnumerable<Product> filteredProducts = _allProducts.Where(p => p.OnStock > 300);

‘p’ is the input parameter to the function, which will be a Product object from _allProducts. Then we have the lambda operator followed by the method body which returns a boolean. Just like above we can explicitly show the return statement if we want to:

IEnumerable<Product> filteredProducts = _allProducts.Where(p => { return p.OnStock > 300; });

You can call the input parameter as you wish: ‘p’, ‘prod’, ‘mickeymouse’ etc. The function takes a single parameter so we can omit the parenthesis, but you can also put ‘(p)’ if you want to. If the function accepts more parameters then we would need to add them within parenthesis. You can then simply iterate through the filtered products:

foreach (Product prod in filteredProducts)
{
	Console.WriteLine(prod.Id);
}

Call the method like this:

ProductService productService = new ProductService();
productService.PlayWithLinq();

…and you’ll see the filtered ids appear.

You can have multiple filtering criteria. As long as the method body returns a bool and accepts a Product it will be fine:

IEnumerable<Product> filteredProducts = _allProducts.Where(p => p.OnStock > 300 && p.Id < 4).OrderBy(p => p.Name);

We can extend our filter by an OrderBy clause which accepts a Function of T and returns a key of type TKey. The key is the property we want to order by:

IEnumerable<Product> filteredProducts = _allProducts.Where(p => p.OnStock > 300).OrderBy(p => p.Name);

Read the finishing post on this topic here.

Events, delegates and lambdas in .NET C# part 4: subscribing to events

Introduction

We saw in the previous post how to add delegates, events and event handlers to our SuperHero class. We also discussed that the standard signature for a delegate in .NET accepts the sender as an objects and another object that inherits from the EventArgs class. You may of course define your delegate as you like but consumers of your class will be expecting the standard signature.

The missing piece now is to wire up those elements. The key is to understand how to add an element to the invocation list. Then as the event fires the elements – methods – will be called one after the other in that list.

Demo

Open the project we’ve been working on in this series. The goal is to create a SuperHero object and subscribe to its events. You can imagine that Program.cs is the police chief who sends out a hero to save the world but wants him/her to report the progress and outcome of the work done.

In Main declare a new SuperHero:

SuperHero superman = new SuperHero();

There’s a number of ways you can subscribe to the events of the superhero. Start typing “superman.” in the editor and IntelliSense will list the available events denoted by a lightning bolt. You add elements to the invocation list with the “+=” operator. So type…

superman.WorldSaved +=

…in the editor and you’ll see that IntelliSense is trying to help you by automatically suggesting a method that will be created for you and which matches the delegate signature. Press TAB twice in order for this to happen. You should have the following method in Program.cs:

static void superman_WorldSaved(object sender, WorldSavedEventArgs e)
{
	throw new NotImplementedException();
}

This is called delegate inference. You didn’t have to new up a delegate yourself. The compiler will do it for you in the background.

Another way to get to the same result is to new up a WorldSavedHandler delegate and pass in the method that will be added to the invocation list:

superman.WorldSaved += new DelegatesIntro.WorldSavedHandler(superman_WorldSaved);

You can test to pass in a method that does not match the delegate signature: Visual Studio will complain immediately.

You can do it either way, it doesn’t make any difference to the outcome. The first option is probably more convenient as Visual Studio is guaranteed to create a method with the correct signature and you can save some code and time.

Modify the method to show some message on the console window:

static void superman_WorldSaved(object sender, WorldSavedEventArgs e)
{
	StringBuilder superHeroMessageBuilder = new StringBuilder();
	superHeroMessageBuilder.Append("Superhero reporting progress! Name: ")
		.Append(e.SaviourName).Append(", has been working for ").Append(e.WorkHasBeenOngoingHs)
		.Append(" hours, ").Append(" date of next occasion: ").Append(e.DateOfNextCatastrophy);
	Console.WriteLine(superHeroMessageBuilder.ToString());
}

The next step is to call on the superhero to finally start working:

superman.SaveTheWorld("Superman", DateTime.UtcNow.AddMonths(3));

Run the code and you’ll see that Superman reports the progress as expected. So you can see that this is kind of a nice way to get multiple values returned by a void method.

Let’s also subscribe to the other event of the superhero:

superman.WorldSavingCompleted += superman_WorldSavingCompleted;

…where superman_WorldSavingCompleted looks like this:

static void superman_WorldSavingCompleted(object sender, WorldSavingCompletedEventArgs e)
{
	StringBuilder superHeroMessageBuilder = new StringBuilder();
	superHeroMessageBuilder.Append("Superhero has saved the world! Name: ").Append(e.Saviour)
		.Append(", time spent saving the world: ").Append(e.HoursItTookToSaveWorld).Append(", message from the superhero: ")
		.Append(e.MessageFromSaviour);
	Console.WriteLine(superHeroMessageBuilder.ToString());
}

Run the code and you’ll see that the correct methods are called when the events fire.

If you want to remove a method from the invocation list then you can use the “-=” operator. If you insert the following – admittedly senseless – code, then you won’t see when the superhero has finished saving the world:

superman.WorldSavingCompleted += superman_WorldSavingCompleted;
superman.WorldSavingCompleted -= superman_WorldSavingCompleted;

Anonymous methods

So far we have declared the elements that react to events as standalone methods. There’s nothing wrong with that at all, but it’s not the only way. As an alternative you can embed the actions in something called an anonymous method which can only be used at the source of the subscription, i.e. where the “+=” operator is used. An anonymous method has no name and may look quite strange at first. You may have heard of “lambdas” before, but they are not the same thing as anonymous methods. They are similar features but still not quite the same. We’ll be looking into lambdas in a later post.

Anonymous methods are defined by the “delegate” keyword. It is followed by the input parameter declarations and finally the method body in curly braces. You close the whole statement with a semi-colon ‘;’.

So we can rewrite…

superman.WorldSavingCompleted += superman_WorldSavingCompleted;


static void superman_WorldSavingCompleted(object sender, WorldSavingCompletedEventArgs e)
{
	StringBuilder superHeroMessageBuilder = new StringBuilder();
	superHeroMessageBuilder.Append("Superhero has saved the world! Name: ").Append(e.Saviour)
		.Append(", time spent saving the world: ").Append(e.HoursItTookToSaveWorld).Append(", message from the superhero: ")
		.Append(e.MessageFromSaviour);
	Console.WriteLine(superHeroMessageBuilder.ToString());
}

…as follows:

superman.WorldSavingCompleted += delegate(object sender, WorldSavingCompletedEventArgs e)
{
	StringBuilder superHeroMessageBuilder = new StringBuilder();
	superHeroMessageBuilder.Append("Superhero has saved the world! Name: ").Append(e.Saviour)
		.Append(", time spent saving the world: ").Append(e.HoursItTookToSaveWorld).Append(", message from the superhero: ")
		.Append(e.MessageFromSaviour);
	Console.WriteLine(superHeroMessageBuilder.ToString());
};

We declare that whatever happens in case the event is fired, it is done right at the source. Note that this method can only be used “here and now” and not be called from anywhere else: it cannot be reused in other words. You may take this approach in case the method body is very simple and don’t want to write a dedicated method for it. In case the method body gets too long then you might want to break it out into a separate method.

We’ll start discussing lambdas, Func of T and Action of T in the next post.

Events, delegates and lambdas in .NET C# part 3: delegates with events in action

Introduction

In the previous part of this series we looked at some examples of delegates. We also discussed the basics of events in .NET. We’re now ready to see some custom events in action.

Demo

Open the project we’ve been working on in this series. Add a new class to the project called SuperHero. Add the following method stub to SuperHero.cs:

public void SaveTheWorld(string saviourName, DateTime dateForNextCatastrophy)
{

}

Also, add the same delegate as we had before in Program.cs:

public delegate void WorldSavedHandler(string saviourName, DateTime dateForNextCatastrophy);

You can also put this is a separate class, it’s up to you.

Let’s say that an external class, such a police chief calls SuperHero to save the world and wants to monitor the progress. SaveTheWorld is void so we cannot read out anything from this method. However, we can raise events. We now know how to declare events so let’s add one to SuperHero.cs:

public event WorldSavedHandler WorldSaved;

The police chief will want to know when the world has been saved, i.e. the superhero’s work has completed. We can add an event handler for that. Add the following code just below the event declaration:

public event EventHandler WorldSavingCompleted;

EventHandler is the built-in .NET event handler that may look familiar to you from Windows UI programming. It is a delegate that does not return anything, accepts an object – the sender – and an EventArgs argument. So this is just a short-hand solution for a case where we don’t have any specialised event arguments. We only want to notify all listeners that the work has been completed. Note that EventHandler has a generic form as well: EventHandler of type T : EventArgs. Use this version if you want to specify a more specialised EventArgs class than the default empty EventArgs:

public event EventHandler<WorldSavingCompletedEventArgs> WorldSavingCompleted;

Then when you raise this event you’ll have to provide WorldSavingCompletedEventArgs to it instead of just EventArgs. Later on we’ll see an example of this.

We have now declared the events. The next step is to raise them. There are basically two ways to do that. One is to call an event like you would call a method:

if (WorldSaved != null)
{
	WorldSaved(saviourName, dateForNextCatastrophy);				
}

Another way is to extract the delegate from the event and invoke it:

WorldSavedHandler handler = WorldSaved as WorldSavedHandler;
if (handler != null)
{
	handler(saviourName, dateForNextCatastrophy);
}

Why do we check for a null value? It’s because if no other object has signed up with the event, i.e. there’s nothing in the invocation list, then the event will be null and you’ll get a null pointer exception if you try to raise it. It is the same as trying to call a method of an object that has not been initialised.

A common practice is to raise the event in a dedicated method and give that method a special name: ‘On’ + the name of the event, kind of like the familiar “OnClick” and “OnSelectedItemChanged” etc. methods. This is not a must for the event to work, only a possible way to organise your code:

public void SaveTheWorld(string saviourName, DateTime dateForNextCatastrophy)
{
	OnWorldSaved(saviourName, dateForNextCatastrophy);
}

private void OnWorldSaved(string saviourName, DateTime dateForNextCatastrophy)
{
	if (WorldSaved != null)
	{
		WorldSaved(saviourName, dateForNextCatastrophy);
	}
}

Let’s say that the police chief wants to monitor the superhero’s progress every hour. We’ll also hard code the duration of the superhero’s work to 4 hours to make this simple. So we’ll raise a WorldSaved event every hour to report some progress. At the end of the 4 hours we’ll raise a WorldSavingCompleted event to tell the world that the superhero has finished:

public void SaveTheWorld(string saviourName, DateTime dateForNextCatastrophy)
{
	int hoursToSaveTheWorld = 4;
	for (int i = 0; i < hoursToSaveTheWorld; i++)
	{
		OnWorldSaved(i + 1, saviourName, dateForNextCatastrophy);
		Thread.Sleep(1000);
	}
	OnWorldSavingCompleted();
}

private void OnWorldSaved(int hoursPassed, string saviourName, DateTime dateForNextCatastrophy)
{
	if (WorldSaved != null)
	{
		WorldSaved(string.Concat(saviourName, " has been working for ", hoursPassed, " hour(s)"), 
			dateForNextCatastrophy);
	}
}

private void OnWorldSavingCompleted()
{
	if (WorldSavingCompleted != null)
	{
		WorldSavingCompleted(this, EventArgs.Empty);
	}
}

So we report every hour worked by the superhero. In the OnWorldSavingCompleted method we raise the default .NET event which accepts the sender as an object and an EventArgs class. The sender of the event is ‘this’, i.e. the current SuperHero object. We don’t have any data to transmit to the listeners so we use the EventArgs.Empty convenience method. We’ll see later on how to send your data with your custom EventArgs object.

This is quite a nice way of getting sort of multiple return values out of void methods. Indeed, all listeners will be notified of the events raised by the superhero.

Custom event arguments

We’ve seen two ways to create delegates in this post: directly with the ‘delegate’ keyword and by using the built-in EventHandler class that is a wrapper around a delegate. Before we see how to subscribe to these events from the outside we need know how to pass custom event arguments.

The usual and standard way in .NET to create events is by specifying a method signature where the handling method will accept the sender as an object and an EventArgs. You must have seen that before if you did any Windows GUI development. We’ve also seen an example of that in OnWorldSavingCompleted(). However, that is kind of limiting as the default EventArgs is – almost – empty, you cannot supply your own messages to it.

Creating a custom EventArgs is very easy: create a class and inherit from the EventArgs object. You are then free to put an as many properties as you wish. You don’t need to worry about extending a parameter list of some delegate, you can just add new properties to your event args class. Add the following class to the project:

public class WorldSavingCompletedEventArgs : EventArgs
{
	public string Saviour { get; set; }
	public DateTime TimeForNextCatastrophy { get; set; }
	public int HoursItTookToSaveWorld { get; set; }
        public string MessageFromSaviour { get; set; }
}

The naming convention is to take the name of the event and attach ‘EventArgs’ to it. All the data that needs to be wired to the listeners is now encapsulated within this event args object. It is easy to extend and the properties are easily extracted from it.

Let’s clean up the WorldSavedHandler delegate. Add the following custom event args:

public class WorldSavedEventArgs : EventArgs
{
	public string SaviourName { get; set; }
	public DateTime DateOfNextCatastrophy { get; set; }
}

The WorldSavedHandler will take the following form:

public delegate void WorldSavedHandler(object sender, WorldSavedEventArgs e);

You’ll get compiler errors because we’ve changed the signature of the handler, we’ll correct it in a bit. As hinted at above the EventHandler object has a generic form to specify the type of the event handler. An advantage of using the EventHandler class will ensure that you’re sticking to the standard event signature. Modify the WorldSavingCompleted event handler to the following:

public event EventHandler<WorldSavingCompletedEventArgs> WorldSavingCompleted;

We can keep both examples, i.e. the delegate and the EventHandler in this demo project so that you can see both approaches, but in practice it’s more convenient to just stick to EventHandler and EventHandler of T. Using the EventHandler object saves having a separate delegate. Use the delegate-event-pair approach if you need access to the delegate on its own, i.e. without the matching event. Let’s clean up our code so that it compiles:

public delegate void WorldSavedHandler(object sender, WorldSavedEventArgs e);

public class SuperHero
{
	public event WorldSavedHandler WorldSaved;
	public event EventHandler<WorldSavingCompletedEventArgs> WorldSavingCompleted;

	public void SaveTheWorld(string saviourName, DateTime dateForNextCatastrophy)
	{
		int hoursToSaveTheWorld = 4;
		for (int i = 0; i < hoursToSaveTheWorld; i++)
		{
			OnWorldSaved(i + 1, saviourName, dateForNextCatastrophy);
			Thread.Sleep(1000);
		}
		OnWorldSavingCompleted(hoursToSaveTheWorld, "Yaaay!", saviourName, dateForNextCatastrophy);
	}

	private void OnWorldSaved(int hoursPassed, string saviourName, DateTime dateForNextCatastrophy)
	{
		if (WorldSaved != null)
		{
			WorldSavedEventArgs e = new WorldSavedEventArgs()
			{
				DateOfNextCatastrophy = dateForNextCatastrophy
				, SaviourName = saviourName
				, WorkHasBeenOngoingHs = hoursPassed
			};
			WorldSaved(this, e);
		}
	}

	private void OnWorldSavingCompleted(int totalHoursWorked, string message, string saviour, DateTime timeOfNextCatastrophy)
	{
		if (WorldSavingCompleted != null)
		{
			WorldSavingCompletedEventArgs e = new WorldSavingCompletedEventArgs()
			{
				HoursItTookToSaveWorld = totalHoursWorked
				, MessageFromSaviour = message
				, Saviour = saviour
				, TimeForNextCatastrophy = timeOfNextCatastrophy
			};
			WorldSavingCompleted(this, e);
		}
	}
}

You’ll see the revised delegate and event handler definitions. They follow the sender/eventargs convention. You also see how easy it is to wire data through the custom event args to the listeners.

Now the SuperHero class is ready to work and make announcements. But no-one is listening yet to catch those event notifications. We’ll see how to do just that in the next post.

Events, delegates and lambdas in .NET C# part 2: delegates in action

Introduction

In the previous installment of this series we looked at the foundations of delegates, events and event handlers. It’s now time to see them in action.

Demo

Open Visual Studio 2012/2013 and create a new Console application with .NET 4.5 as the underlying framework. I haven’t tested the code with .NET4.0 or .NET 3.5 but I think it should work with those frameworks as well.

In Program.cs add the following delegate declaration just above the Main method:

public delegate void WorldSavedHandler(string saviourName, DateTime dateForNextCatastrophy);

So this is a delegate for when some superhero saves the world for the nth time. It is void, it has a name and accepts two parameters: a string and a date. Note that it’s customary but not mandatory to name delegates with the word ‘Handler’ attached.

Add the following methods that match the delegate signature:

static void WorldSaved(string saviour, DateTime nextTime)
{
	Console.WriteLine(string.Concat("World saved by ", saviour, ", get ready again by ", nextTime));
}

static void WorldSavedAgain(string saviour, DateTime nextTime)
{
	Console.WriteLine(string.Concat("World saved this time by ", saviour, ", get ready again by ", nextTime));
}

In Main you can instantiate a delegate and hook up a callback method as follows:

WorldSavedHandler worldSavedHandler = new WorldSavedHandler(WorldSaved);

As you type the declaration in the editor IntelliSense will indicate that the delegate is expecting a void method that accepts a string and a date. If you try to pass in a method that doesn’t match this signature you’ll get a compile error. Add another delegate declaration to Main:

WorldSavedHandler worldSavedAgainHandler = new WorldSavedHandler(WorldSavedAgain);

We have set up two pipelines: worldSavedHandler which sends its data to WorldSaved and worldSavedAgainHandler which sends its data to WorldSavedAgain. We can invoke the delegates the same way as we normally call a method:

worldSavedHandler("Bruce Willis", DateTime.UtcNow.AddYears(2));
worldSavedAgainHandler("Spiderman", DateTime.UtcNow.AddMonths(3));

Console.ReadKey();

I added the call to ReadKey so that the console window doesn’t just close down.

Run the program and you’ll see the appropriate output in the console window.

Why on earth are we bothering with this? Up to now this looks like some funny way of calling methods. Consider the following method which accepts our delegate type:

static void SaveWorld(WorldSavedHandler worldSaved)
{
	worldSaved("Bruce Willis", DateTime.UtcNow.AddMonths(5));
}

In Main comment out the two delegate calls…:

worldSavedHandler("Bruce Willis", DateTime.UtcNow.AddYears(2));
worldSavedAgainHandler("Spiderman", DateTime.UtcNow.AddMonths(3));

…and add the following instead:

SaveWorld(worldSavedHandler);

This is stating that we need to save the world and we have 2 possible delegates to give this work to. We entrust worldSavedHandler with this task so we pass it in. An analogy from the real world is when a boss decides the software development team needs to build the data access layer and appoints a particular team member to do just that. In other words the boss delegates the job to a particular programmer, i.e. a handler.

We know that worldSavedHandler will call WorldSaved. SaveWorld gets the delegate and will invoke whatever was passed to it. SaveWorld does NOT know which handler the delegate will call. From its point of view it could be any method with the correct signature, so it’s quite a dynamic setup. The delegate could have been passed in from whichever external object to the SaveWorld method. SaveWorld passes in Bruce Willis and now + 3 months to some unknown method.

Run the program and you’ll see that WorldSaved was called. Now, without changing SaveWorld directly, you can modify its outcome just by providing a different delegate:

SaveWorld(worldSavedAgainHandler);

Run the program and WorldSavedAgain was called as expected without changing SaveWorld at all.

Let’s look at multicasting quickly. Comment out the call to SaveWorld in Main and instead add a third delegate declaration:

WorldSavedHandler worldSavedOnceMoreHandler = new WorldSavedHandler(WorldSavedOnceMore);

…where WorldSavedOnceMore looks like this:

static void WorldSavedOnceMore(string saviour, DateTime nextTime)
{
	Console.WriteLine(string.Concat("World saved once again by ", saviour, ", get ready again by ", nextTime));
}

There are different way to build an invocation list. The following chains our three delegates together:

worldSavedHandler += worldSavedAgainHandler;
worldSavedHandler += worldSavedOnceMoreHandler;

worldSavedHandler("Superman", DateTime.UtcNow.AddMonths(3));

You’ll see that all three method handlers were called.

The below is equivalent to the above:

worldSavedHandler += worldSavedAgainHandler + worldSavedOnceMoreHandler;
worldSavedHandler("Superman", DateTime.UtcNow.AddMonths(3));

The following will wipe out the first handler:

worldSavedHandler = worldSavedAgainHandler + worldSavedOnceMoreHandler;
worldSavedHandler("Superman", DateTime.UtcNow.AddMonths(3));

This time only WorldSavedAgain and WorldSavedOnceMore are called.

You’ll also see that each handler is called in the order they were added to the invocation list. This way we can invoke multiple handlers by calling just one delegate, in this case worldSavedHandler.

Returning a value from a delegate

Delegates can return values, they don’t need to be void all the time. Add the following delegate to Program.cs:

public delegate string SomeoneJustShoutedHandler(string who, DateTime when);

Add the following handlers:

static string SomeoneShouted(string who, DateTime when)
{
	return string.Concat(who , " has shouted on ", when);
}

static string SomeoneShoutedAgain(string who, DateTime when)
{
	return string.Concat(who, " has shouted on ", when);
}

static string SomeoneShoutedOnceMore(string who, DateTime when)
{
	return string.Concat(who, " has shouted once more on ", when);
}

…and 3 delegate declarations with the delegate chain:

SomeoneJustShoutedHandler someoneShoutedHandler = new SomeoneJustShoutedHandler(SomeoneShouted);
SomeoneJustShoutedHandler someoneShoutedAgainHandler = new SomeoneJustShoutedHandler(SomeoneShoutedAgain);
SomeoneJustShoutedHandler someoneShoutedOnceMoreHandler = new SomeoneJustShoutedHandler(SomeoneShoutedOnceMore);

someoneShoutedHandler += someoneShoutedAgainHandler + someoneShoutedOnceMoreHandler;
string finalShout = someoneShoutedHandler("The neighbour", DateTime.UtcNow);
Console.WriteLine("Final shout: " + finalShout);

Run the code and you’ll see that it’s only the third string that’s returned. It’s logical as we cannot have multiple return values in C#. You can get the individual return values by calling the delegates separately. However, with an invocation list the last delegate in the list will win.

Adding events

We’ve seen that using delegates can work fine without adding events to the code. However, delegates coupled with events help us raise those events and propagate the event arguments to all listeners in the invocation list.

An event is declared using the ‘event’ keyword in C#. It is also declared with the type of the delegate that raises the event as an event by itself cannot do much. Events are the standard way of providing notifications to all listeners. The data will be supplied using the delegate declared in conjunction with the event. In .NET programming you’ll probably rarely see delegates used without events although it’s certainly possible as we’ve seen above. You also give a name to the event. Here’s an example of an event declaration:

public event WorldSavedHandler WorldHasBeenSaved;

Listeners will be able to sign up with the event and receive a notification when the event has fired. It is equivalent to building the invocation list we saw above. So an event is really nothing but a wrapper around a delegate.

There’s also a more complex way of defining an event using the add/remove accessors:

private WorldSavedHandler WorldHasBeenSaved;
public event WorldSavedHandler WorldSaved
{
	[MethodImpl(MethodImplOptions.Synchronized)]
	add
	{
		WorldHasBeenSaved = (WorldSavedHandler)Delegate.Combine(WorldHasBeenSaved, value);
	}
	[MethodImpl(MethodImplOptions.Synchronized)]
	remove
	{
		WorldHasBeenSaved = (WorldSavedHandler)Delegate.Remove(WorldHasBeenSaved, value);
	}
}

This provides more control over how listeners are added to and removed from the invocation list. You’ll probably not see this kind of event declaration too often. However, if you see it somewhere then you’ll now know what it means.

We have a private delegate of type WorldSavedHandler. Then we see the event declaration that conforms to the example provided above. The add accessor defines how a listener is added to the invocation list. The remove accessor does the opposite. The actions are synchronised to make sure that if different threads perform the same action we don’t run into concurrency issues. The ‘value’ keyword indicates the listener that’s going to be added to the invocation list. The Delegate.Combine method takes the delegate we already have and adds in the new one. The remove accessor works with the Delegate.Remove method that removes ‘value’ from the invocation list.

You might use this type of event declaration if you have extra logic on who and when is allowed to be listed on the invocation list. The access may be limited to some special objects that fulfil certain rules.

Now that we know more about events than we ever wanted to we can create some custom events in our code. We’ll actually do that in the next part.

Events, delegates and lambdas in .NET C# part 1: delegate basics

Introduction

I believe that learning the basic features of a popular OO language, such as C# or Java is not too difficult. Obviously you’ll need a positive mindset towards programming in general otherwise you’re bound to fail but that’s true for every discipline. The basic structures found in C#, such as classes, properties, constructors, methods, functions, interfaces and the like are quite straightforward and simple to use even after a couple of months’ worth of training. If you have a Java or C++ background then you can start to be productive with C# after some weeks even.

However, there are some language features that stick out a little as they are slightly more cryptic: events, delegates and lambda expressions. You can certainly come up with others, but my personal experience is that learning these features thoroughly takes more time than the ones listed above.

This series of posts will be dedicated to these language elements of C#.

The building blocks

If you’ve ever done any Windows app development then you must have seen examples of events and event handlers: button click event, list selection changed event, on mouse over event etc. You added an event and an event handler to a button just by double-clicking on it in the visual editor and the following elements were wired together for you in the background:

  • Event: notifications originating from objects. These notifications can be used to notify other elements – objects – in the application that may be interested in the event, such as when a new order was placed or a party is about to start. Then the objects listening to those events can perform some work dedicated to them: serve the drinks, order the pizzas, let in the guests etc.
  • Event raiser, a.k.a. the Sender: the object that raises the event. They typically don’t know anything about the objects listening to the events raised by themselves
  • Event handler: the handler that ‘caught’ the event raised by the button
  • Delegate: the glue between the button and the event handler. This is usually hidden in the designer cs file of the Form created by Visual Studio, so you may not even have come across it. Without delegates the event raised would not get to the listening objects and their event handlers
  • Event arguments, or EventArgs: the arguments that the Sender is sending to the event handler with the event raised. This can include anything important for the handler, such as the selected item index, the venue for the party, the items that were ordered etc.

Probably the most confusing element in this list is delegates. They are typically described by adjectives such as ‘odd’, ‘strange’ and ‘unusual’. A delegate, also called a function pointer, is a specialised class that derives from the MulticastDelegate base class. As noted above, it connects the event with the event handler. It’s called a function pointer because the event handler will be a function, i.e. a method, and it points at the event handler from the event and wires the event arguments in between.

An event handler will process the data received from a delegate. It is a method with a special signature that must accept a sender of type ‘object’ and an EventArgs parameter or one that’s derived from the EventArgs class. EventArgs objects are normal C# objects with properties. You can easily define your custom event args by deriving from the EventArgs class. You can put in all sorts of properties into your event args that may be interesting for those waiting for the event. A button click event handler may look like this:

public void btnOrderItems_Click(object sender, EventArgs e)
{
      //do something
}

A custom event handler can have the following form:

public void OrderPlaced(object sender, OrderPlacedEventArgs e)
{
      //do something with the order
}

Delegates

You can create delegates with the ‘delegate’ keyword in C#, example:

public delegate void GraphClicked(GraphType graphType, Point clickCoordinate);

It’s void as nothing is returned, data is only sent one way. In this example the delegate’s name is GraphClicked and it accepts two parameters: a graph type and the click coordinates. This declaration is a blueprint for the method, i.e. the handler, that will receive the data from the delegate. The handler method must match this signature otherwise the code will not compile: it must also receive a graph type and the click coordinates. An example of a matching handler:

public void GraphClicked_Handler(GraphType type, Point coords)
{
     //do something
}

Note that the parameter names don’t necessarily match those in the delegate, but the types must match.

The delegate keyword is special in .NET as the compiler does some magic when it sees it declared. It creates another object that inherits from the MulticastDelegate class behind the scenes which in turns derives from the Delegate base class. Multicast delegate means that a single message can be sent to a range of objects through a range of pipelines. Note that you cannot directly derive from the Delegate or the MulticastDelegate classes. You do it indirectly using the delegate keyword and the compiler will do the inheritance trick for you.

The list of pipelines of a multicast delegate is called the Invokation List. The delegates listed here are invoked sequentially.

Now that we have a delegate you can easily instantiate one:

GraphClicked graphClicked = new GraphClicked(GraphClicked_Handler);

So you see a delegate is a class that you can instantiate using the new keyword. Notice that you must specify the handler in the constructor of the delegate. We say that when the graphClicked delegate is invoked then the GraphClicked_Handler method should be called.

You can invoke the graphClicked delegate as follows:

graphClicked(GraphType.Line, new Point(1,1));

So you invoke it like a method and provide the necessary parameters. This adds one delegate item to the invocation list.

There’s nothing stopping you from instantiating several delegates of the same type:

GraphClicked niceGraphClicked = new GraphClicked(NiceGraphClicked_Handler);
GraphClicked uglyGraphClicked = new GraphClicked(UglyGraphClicked_Handler);

These delegates point to two different handlers: NiceGraphClicked_Handler and UglyGraphClicked_Handler. What if you want niceGraphClicked not only invoke NiceGraphClicked_Handler but UglyGraphClicked_Handler as well? In other words you want to extend the invocation list of niceGraphClicked to two items: NiceGraphClicked_Handler but UglyGraphClicked_Handler. It couldn’t be simpler:

niceGraphClicked += uglyGraphClicked;

So now when niceGraphClicked is raised…:

niceGraphClicked(GraphType.Cylinder, new Point(2, 3));

…then both NiceGraphClicked_Handler but UglyGraphClicked_Handler will be called in the same order as they were added to the invocation list.

This post has given you the absolute basics of delegates, events and event handlers. We’ll look at a couple of examples from scratch in the next post.