CategoryCreate and implement events and callbacks

Events

Events allow us two things:

  1. If something important has occurred object notifies its subscribers about that occurrence.
  2. Objects that listen to another object are notified about changes of that object.

To declare event, you use event keyword followed by the type of delegate for the event, meaning we have to declare delegate before we can use event.

Typically, to raise an event, you would use protected void method. Name of that method by convention goes should be like this: OnEventName. Method should raise event  and provide two parameters object and EventArgs. Delegate upon whose type event uses should have two parameters: Object parameter is usually named sender and EventArgs parameter is named args. sender parameter is the source of the event. You should use EventArgs if you do not intend to send any parameters to subscriber, if on the other hand you wish to supply parameters create an class that inherits from from EventArgs and use that class as an parameter.

Example:

Lets create an application that is used to insert an employee to database. Upon inserting and after inserting few people should be notified, meaning we will have two events.

  • First, when we start inserting employee in database, we will notify our System Administrator that process of inserting has started. Also we will provide Sys Admin with DateTime value which will represent time when insert operation has started.
  • Second, after employee has been inserted in database, CEO, Website and System Admin will be notified.

You can also download entire solution for easier readability.

If you prefer using Action delegate instead of declaring delegates you can easily doe that. Just replace following code in HRDepartment class:

For now we will finish our journey with Delegates and return to Reflection.

 

Lambda expressions

A lambda expressions are an anonymous function that helps us write easy to read code.

Let’s see how we can achieve this. First we will take example from previous post about anonymous methods:

We can simplify this code by  removing delegate keyword and inserting => operator between anonymous method’s parameters and statement.

How do you pronounce => operator?

There are quite a few names for => operator. Here are a few typical names:

  • Goes to
  • Maps
  • Such that
  • Becomes

Lambda expressions do not look like a easier way to write delegates, can we for example remove delegate declaration?

You are correct. We can simplify thing even more with Action and Func.

Action

Action is a generic delegate type that describes a method that does not return a value. Action can have 16 overloads, of which not a single one describes a return type. You can picture action like a method with a void return type.

Action example

Code here is not deleted but commented out for you to see benefits of using Action. First of we do not need to declare delegate and lastly because we do not need to declare delegate we are free to decide upon our types while writing an Action.

Func

Func is a generic delegate type that describes a method that has an return a value. Func can have 17 overloads, but note that last type is your return type.

Func Example

Same as Action but note, that when looking at our sumOfTwoNumber Func, third int type is our return type.

We will now continue our journey with delegates by learning about events.

 

Anonymous methods

Anonymous methods allow us to create delegate methods inline.

What does that mean?

Let’s create a simple delegate whose role is to sum two numbers:

Would not it be nice if we could get rid of the SumTwoNumber method and just write it’s content while we instantiate delegate ? Yes it would and we can do it! Steps are:

  1. While instantiating your delegate, remove new… part.
  2. Write delegate keyword followed by input parameter in round brackets.
  3. Type your code inside curly brackets.

What we essentially did is we created a method without method name and thus we created anonymous method. Don’t believe me? Look again at the same code that has been reformatted a bit:

When you mentioned we can write delegate methods inline, does that mean we can write methods in one line only?

No, you can write as many lines as you want. Notice semicolon (;) on line 12, you can write additional code below. But beware of that feature, because if you write too many lines whole purpose of anonymous methods disappears and that is readability. Generally you would like to keep it to 1-3 lines, more than that would best be very good candidate for standalone method.

How do i know which parameters and return types to use wile writing an anonymous methods?

Your delegate tells you that information. In our example SumTwoNumberDelegate delegate expects return type int and two int input parameters, so that is what we provided him within anonymous method.

Anonymous methods are awesome! Are there any drawbacks to using them?

You would normally use delegate, instead of method, if you do not intend to use a function multiple times. On the other hand it makes no sense to write same anonymous method multiple times if you can reuse one method + it is easier to maintain that one method than multiple anonymous methods.

Can i make my code even simpler?

Yes you can, by using lambda expressions!

 

Delegates part 1

A delegate is a reference type, type-safe function(method) pointer. Delegates are used to invoke the method through the delegate instance. To invoke method,  delegates methods signature and return type must be same as that of a delegate.

You declare delegate similar to declaring the method:

How do we use delegates?

Lets create simple console application that will use method to display value:

This class does its intended yob nicely, but we can expand it by adding delegate. First we must declare delegate outside our class and instantiate our newly created delegate inside Main method then we can use our delegate to pass the value to our function.

Q: This look very complicated process just to invoke function. Why would i ever need to use delegates?

A: Yes it takes some extra work to create delegates but in next example you will see where delegates make much more sense.

Why do we use delegates?

Imagine that you need to create application for HR department and in that application you need to predict salary increase for employees that are employed full-time in that company. You would create application that behaves  like this:

Here we have Employee class that has necessary properties and  NextYearSalary method. NextYearSalary that takes List of Employees and checks each employee for his IsFullTime status, if that status is true then it multiplies employees years of service in company with 1% then multiplies it again with current salary. That way we get potential salary increase and print it to the console. We compile our program and ship it to all companies that use our application.

After some time we receive request from another company. Other company wants to see potential salary increase not for its full time employees but for those employees who have worked there for at least 3 years.

We could expand NextYearSllary method to accommodate that request or create another method only for that company, but these two approaches are not good solution for our problem because we always tend to have clean code and because second approach breaks DRY principle. Instead we will use delegates:

First wee took a look in NextYearSalary method. Inside our foreach loop we found if statement that needed to be changed. If statement is a boolean and checks Employee object so we created delegate that returns bool value and takes Employee object as a parameter. Now we needed to create method that matches that signature, so we created PotentialSalaryIncreaseForFullTimeEmployees method in our Main method. Next step was to expand signature of NextYearSalary method with SalaryIncreaseDelegate  delegate and replace condition of if statement with our delegates variable. Lastly, we call of NextYearSalary method in Main method with missing delegate variable.

Exercise 1:

Try to create method that:

  • can be used for SalaryIncreaseDelegate
  • can decide which Employees next years potential salaries will be displayed using NextYearSalary method for those employees that have worked in company at least 3 years.

Exercise 2:

Try to create delegate that will emulate NextYearSalary logic for expected salary:

Continue to Delegates part 2

© 2019 LearnC#WithDarko

Theme by Anders NorenUp ↑