Showing posts with label Delegates. Show all posts
Showing posts with label Delegates. Show all posts

Friday, July 9, 2021

A Collection of 2020 Recorded Presentations

2020 was "interesting". One good thing that came out of it is that I had the chance to speak remotely for some user groups and conferences that I would not normally get to attend in person. Many of those presentations were recorded. Here's a list for anyone who is interested

Abstract Art: Getting Abstraction "Just Right" (Apr 2020)

Modern Devs Charlotte

Abstraction is awesome. And abstraction is awful. Too little, and our applications are difficult to extend and maintain. Too much, and our applications are difficult to extend and maintain. Finding the balance is the key to success. The first step is to identify your natural tendency as an under-abstractor or an over-abstractor. Once we know that, we can work on real-world techniques to dial in the level of abstraction that is "just right" for our applications.


I'll Get Back to You: Task, Await, and Asynchronous Methods in C# (Apr 2020)

Enterprise Developers Guild

There's a lot of confusion about async/await, Task/TPL, and asynchronous and parallel programming in general. So let's start with the basics and look at how we can consume asynchronous methods using Task and then see how the "await" operator can makes things easier for us. Along the way, we’ll look at continuations, cancellation, and exception handling.


A Banjo Made Me a Better Developer (May 2020)

Dev Around the Sun

What does a banjo have to do with software development? They both require learning. And picking up a banjo later in life showed me 3 things that I've brought into my developer life. (1) You can learn; a growth mindset removes blockages. (2) You don't have to be afraid to ask for help; experienced banjoists/developers can point you in the right direction. (3) You don't have to be perfect before you share what you've learned; it's okay to show what you have "in progress". In combination, these have made me a better banjo player and a better developer.


I'll Get Back to You: Task, Await, and Asynchronous Methods in C# (Jun 2020)

Houston .NET User Group

There's a lot of confusion about async/await, Task/TPL, and asynchronous and parallel programming in general. So let's start with the basics and look at how we can consume asynchronous methods using Task and then see how the "await" operator can makes things easier for us. Along the way, we’ll look at continuations, cancellation, and exception handling.


What's New in C# 8 Interfaces (and how to use them effectively) (Jun 2020)

Southeast Valley .NET User Group
North West Valley .NET User Group

C# 8 brings new features to interfaces, including default implementation, access modifiers, and static members. We'll look at these new features and see where they are useful and where they should be avoided. With some practical tips, "gotchas", and plenty of examples, we'll see how to use these features effectively in our code.


What's New in C# 8 Interfaces (and how to use them effectively) (Jul 2020)

Tulsa Developers Association

C# 8 brings new features to interfaces, including default implementation, access modifiers, and static members. We'll look at these new features and see where they are useful and where they should be avoided. With some practical tips, "gotchas", and plenty of examples, we'll see how to use these features effectively in our code.


I'll Get Back to You: Task, Await, and Asynchronous Methods in C# (Aug 2020)

Code PaLOUsa

There's a lot of confusion about async/await, Task/TPL, and asynchronous and parallel programming in general. So let's start with the basics and look at how we can consume asynchronous methods using Task and then see how the "await" operator can makes things easier for us. Along the way, we’ll look at continuations, cancellation, and exception handling.


Get Func-y: Understanding Delegates in C# (Oct 2020)

St Pete .NET

Delegates are the gateway to functional programming. So let's understand delegates and how we can change the way we program by using functions as parameters, return types, variables, and properties. In addition, we'll see how the built in delegate types, Func and Action, are waiting to make our lives easier. By the time we're done, we'll see how delegates can add elegance, extensibility, and safety to our programming. And as a bonus, you'll have a few functional programming concepts to take with you.


More to Come!

I have a few more recordings from 2021 presentations, and I'll post those soon. As always, if you'd like me to visit your user group, drop me a line. I'll see what I can do about being there online or in person (once in-person stuff is a bit more back to normal).

Happy Coding!

Monday, April 13, 2015

Talk with Dustin Davis on //c0deporn

I had a chat last week with Dustin Davis (@PrgrmrsUnlmtd) about one of my favorite topics: Lambda Expressions.

You can watch the video on YouTube: Getting Started with Lambda Expressions with Jeremy Clark



If you want to have a chat about technology, just drop me a line.

Happy Coding!


Sunday, April 12, 2015

New Video: Demystifying LINQ Methods

I just published Part 2 of my video series on Lambda Expressions and LINQ. You may have heard about Part 1 (Lambda Expression Basics) on This Week on Channel 9 (big thanks to Channel 9 for the mention).

A big problem with LINQ is the apparent chaos of the method signatures:


When we see this for the first time, it seems extremely complex. But once we dive into the different pieces, we see that things aren't as complicated as they seem. And that's exactly what we do in this video: Demystifying LINQ Methods:


While exploring LINQ, we mention a couple of other topics that are covered in separate videos:
As a reminder, Part 1 covers the basics of lambda expressions. And in future videos, we'll look at how LINQ can help us make our code more readable through declarative programming. We'll also take a look at the Join method and the intricacies of using captured variables in "for" loops.

Get links to all of the videos, plus code samples, additional articles, and a PDF walkthrough here: Learn to Love Lambdas (and LINQ, Too!)

Happy Coding!

Monday, April 6, 2015

New Video: Lambda Expression Basics

I just started a new video series based on my presentation Learn to Love Lambdas (and LINQ, Too!). LINQ is one of my favorite tools in C#, and lambda expressions play a key role in using LINQ methods.

Lambdas & LINQ in C# - Part 1: Lambda Expression Basics
In part 1 of the series, we take a look at the syntax of lambda expressions and how to create anonymous delegates. In addition, we look at captured variables which allows us to scope our variables more appropriately.

Watch Part 1 on YouTube (or here):



Future episodes will take a look at how to read and understand the signatures of LINQ methods. This allows us to use LINQ effectively in our code.

Coming Soon!
Part 2: Demystifying LINQ Methods -- 04/12/2015: NOW AVAILABLE!
Part 3: Declarative Programming with LINQ -- 04/14/2015: NOW AVAILABLE!
Plus, bonus episodes that look at the Join method syntax and the dangers of using captured variables with "for" loops.

Lots of good information coming. If you can't wait for the information, be sure to check out the PDF walkthroughs and articles available here: Learn to Love Lambdas (and LINQ, Too!).

Happy Coding!

Sunday, March 29, 2015

Named Delegates Compared to Anonymous Delegates

I love to talk about lambda expressions because they are useful in a lot of situations (especially when using LINQ). Lambda expressions are just anonymous delegates. So the question comes up, What are the differences between named delegates and anonymous delegates?

For an overview of delegates in general, check out "Get Func<>-y: Delegates in .NET" (including a video series). For some more specifics on lambda expressions and anonymous delegates, take a look at "Learn to Love Lambdas (and LINQ, Too)".

There are 4 differences that we'll look at: captured variables, removing assignments, re-use, and visibility.

[Update 3/30: When I originally published this article, I left out re-use and visibility. Since these are so important, I amended this article rather than writing a new one. That's what I get for writing an article when I've had a long day.]

Captured Variables
Advantage: Anonymous Delegates
Anonymous delegates (and therefore lambda expressions) allow us to "capture" a variable that is currently in scope when we assign the delegate. Then we can later use that variable even when it would have normally gone out of scope.

Here's an example (from "Learn to Love Lambdas (and LINQ, Too)" -- check Page 8 of the PDF:


In this scenario, we have a method-level variable called "selectedPerson". This holds the currently selected item from a list box in the UI.

Then inside our lambda expression, we use that "selectedPerson" variable in order to locate a matching item in the list box after we load in fresh data.

The cool part of this is that the body of the lambda expression does not run until *after* the containing method (RefreshButton_Click) has completed. As such, the "selectedPerson" variable would normally go out of scope and be eligible for garbage collection.

But since our lambda expression captured this variable, it is not garbage collected, and it remains available for our anonymous delegate to make use of it. The big advantage to doing this is that we can have a method-level variable in this case. If we had a separate named delegate, then we would need to promote this to a class-level variable so that both methods have access to it. This allows us to scope our variables more appropriately.

Even though we use a lambda expression in our example, this works with other anonymous delegates as well. Other languages refer to this as a "closure". For a little more info on captured variables, check out this article: Lambda Expressions, Captured Variables, and For Loops: A Dangerous Combination.

So captured variables is a big advantage to using anonymous delegates.

Removing Assignments
Advantage: Named Delegates
All delegates are multicast delegates. This means that we can assign multiple methods to a single delegate variable. Then when we invoke the delegate (that is, execute the methods associated with the delegate), all of those methods run.

For an example of multicast delegates, take a look at "Get Func<>-y: Delegates in .NET" or check out the 3rd video in the series: Action<> & Multicast Delegates.

Just like we can add multiple methods, we can also remove those methods (at least when we're using a named delegate). Let's look at some code to see an example of this.

The Base Application
Here's a sample application where we can see the assignment differences:


In this application, we have buttons to add and remove named and anonymous delegates. The numbers will keep a running total of adding and removing. Then when we click the "Click Me!" button, the assigned delegates will execute.

You can get this code from GitHub: jeremybytes/delegates-and-func. This project is in the "BONUS-NamedVsAnonymous" folder of the solution.

The Constructor
Here are the basics of the code-behind for this form:


This is pretty straight-forward. We have 2 private fields to hold our running totals. Then in the constructor, we assign a lambda expression to our "Click" event to clear our output list in the UI.

As a reminder, event handlers are just special kinds of delegates. This means that they have all the properties that we expect with delegates -- including multicasting.

Named Delegates
Here's the code to handle our named delegate buttons:


First, notice our method "NamedDelegate". This method signature matches the event handler for a button: it takes an object and RoutedEventArgs as parameters and returns void. This means that we can assign this to our "Click" event.

The body of our method just outputs "Hello from Named Delegate" to our output list in the UI.

Then notice our "AddNamed_Click" method. This is hooked up to the event of the "Add" button. Here we see that we use "+=" to assign the "NamedDelegate" method as a handler for the event. The "+=" will add this delegate to any existing collection of methods that are already assigned.

The rest of this method manages the running total -- incrementing the count and updating the UI.

Now look at the "RemoveNamed_Click" method. This is hooked up to the "Remove" button. Here we see that we use "-=" to remove the assignment of the "NamedDelegate" method. The effect of this is that it will remove an assignment to this named delegate (assuming that it finds one by that name).

Anonymous Delegates
Now let's look at the code that is hooked up to the anonymous delegate buttons:


This code is similar to the "Add" and "Remove" methods that we have for the named delegates. The difference is that we are using anonymous delegates.

In the "Add" method, when we use "+=" we give it a lambda expression (which is an anonymous delegate). This will put "Hello from Anonymous Delegate" into our output list in the UI.

In the "Remove" method, we use "-=" to attempt to remove the anonymous delegate (just like we did with the named delegate). What we'll find is that this does not work quite like we intend it to.

Running the Application
So now that we have the code, let's run the application to see what happens. First we'll click each of the "Add" buttons 2 times, and then click the "Click Me!" button:


We can see that our running total tells us that we expect to have 2 named delegates and 2 anonymous delegates hooked up to our "Click" event. And we see exactly that in the output.

Now, let's click the "Remove" buttons one time each and see what happens:


This output isn't quite what we expect. Our running totals tell us that we expect to only have 1 named delegate and 1 anonymous delegate assigned. But our output shows that we have 1 named delegate and 2 anonymous delegates.
What this tells us is that the removal of the named delegate was successful, but the removal of the anonymous delegate was not.
Let's try again by clicking the "Remove" buttons again:


At least our results are consistent. The other named delegate was successfully removed, but we see that both anonymous delegates are still attached to our "Click" event.

Deconstructing the Behavior
This behavior makes sense when we take a closer look at what's happening. When we use the "-=" operator, we need to give an identifier that can be used to locate the item that we want to remove. When we have a named delegate, that's easy -- the name is "NamedDelegate", and it can remove the first one that it finds in the list.

But with the anonymous delegate, we don't have access to the name. The compiler generates a name, but we never see that in the code. Because of that, we can't give a valid value that will work with the "-=" operator in order to remove an anonymous delegate.

How Important Is This?
So that question is whether we should be concerned about this. The answer is: maybe. We can still clear out the items attached to the "Click" handler by just saying "xxx.Click = null". But this has the effect of clearing *everything*.

Why do we care whether things stay attached to event handlers? Well, depending on the circumstances, these are generally strong references. What that means is that event handler assignments can prevent the garbage collector from clearing objects from memory. Whether this is important really depends on how we do our assignments, the expected lifetime of our objects, and how we deal with these types of references.

As an alternative, we can use a different construct that will give us a weak reference. This is a reference that does *not* prevent the garbage collector from cleaning up an object. (But this is a topic for another day).

So we can see that being able to easily remove assignments is an advantage of named delegates.

[Update 3/30: When I originally published this article, I left out 2 very important differences: re-use and visibility. They're important enough that I added them on here rather than writing another article.]

Code Re-Use
Advantage: Named Delegates
A really big advantage to having named delegates is that we can reuse the same method throughout our application. If we use an anonymous delegate, we basically in-line the code. This is great for visibility (which we'll see in a bit), but it hampers the ability to reuse the same block of code somewhere else.

Here's an example from Get Func<>-y (also in the 2nd video in the series). In this sample, we have a delegate variable:


This represents a method that takes a "Person" as a parameter and returns a "string". And we assign it based on UI elements (in this case, a set of (badly-named) radio buttons).


This uses some static methods that we have in another class. Here's the code for "LastNameToUpper":


We can see that it matches our delegate signature (takes a "Person" as a parameter and returns a "string"), and it simply returns the last name property of the parameter as upper case.

The other methods look similar. And an advantage to having these separate methods (named delegates) is that we can re-use them in other parts of our application. This allows us to eliminate duplication -- which is good -- and adhere to the DRY principle (Don't Repeat Yourself).

So we can see that re-use is an advantage to using named delegates.

Visibility of Code
Advantage: Anonymous Delegates
There's one more difference that is important when we're talking about delegates, and that is visibility of the code. When we use an anonymous delegate, we basically in-line the code. This means that we don't need to go somewhere else to find the functionality.

Let's go back to the example that we just looked at:


If we want to know what any of these methods do, we need to click into them. For the most part, the method names tell us what they are doing, but we would need to click into the "FullName" method to know exactly what format comes out.

When we switch these to anonymous delegates (and in-line the code), all of the code is right in front of us:


Now we can see exactly what each delegate does. If we look at the last assignment now (which was previously assigned to the "FullName" method), we see that it formats the name as "LastName [comma] [space] FirstName".

The great thing about this is that we don't need to go somewhere else to find that. It's right here in front of us.

This is especially useful when we have lambda expressions in LINQ methods (which I really like). Now if our anonymous delegates get more than a few lines long, then they can become difficult to read and we may want to extract them as separate methods. But if they are short, it's great to have the code right in front of us.

So, visibility of the code is an advantage for anonymous delegates.

Wrap Up
There are pros and cons to pretty much every construct that we work with in programming. Delegates are no different.
Captured Variables: Advantage Anonymous Delegates
Removing Assignments: Advantage Named Delegates
Code Re-Use: Advantage Named Delegates
Visibility of Code: Advantage: Anonymous Delegates
As developers, we get to make these types of decisions all the time. It's important that we understand our tools so that we can make the best choices for our particular needs.

Happy Coding!

Wednesday, December 10, 2014

New Video Series: C# Delegates

I've been talking about delegates for several years now. As with most of my topics, this is something that took a while for me to wrap my head around. But once I "got it", I saw how useful delegates are. They let us use methods as parameters to other methods -- this let's us incorporate functional-style programming into our C# code. In addition, since lambda expressions are simply anonymous delegates, they are much easier to understand once we have a good handle on what standard delegates are.

To help other folks "get" delegates, I just put together a video series on C# Delegates. Check it out on YouTube.

C# Delegates (Playlist)
Do you use delegates in .NET? If so, then Func and Action are just waiting to make your life easier. Not using delegates? Maybe you should. We'll take a look at what delegates are, why you would want to use them, and how to use Func and Action to tie things all together (with a few Lambdas thrown in just for fun).
  • Part 1: Basics
    In this video (first of a series), we'll look at the basics of delegates, including how to create a new delegate type, how to pass a delegate as a parameter to a method, and how to select what method we execute at runtime rather than compile-time. Along the way, we'll see how delegates can help us adhere to the S.O.L.I.D. principles.
  • Part 2: Getting Func<>-y (+ Lambdas)
    In this video, we'll see how we can use the built-in delegate type "Func" instead of using a custom delegate. In addition, we'll see how lambda expressions can make our code very compact and easy to read.
  • Part 3: Action<> and Multicast Delegates
    In this video, we'll use the built-in "Action" delegate. Along the way, we'll see how multicast delegates allow us to run multiple methods by invoking a single delegate variable.
For the sample code and supplemental articles, head over to my website: Get Func<>-y: Delegates in .NET

So in less than an hour, you can understand delegates a bit better. They are pretty awesome. And it's an important step to get a firm grasp one of my favorite topics: lambda expressions.

Happy Coding!

Wednesday, June 18, 2014

New Video: Generics in Methods & Delegates

Part 3 of the C# Generics video series is now available. This time we're talking about generics in methods and delegates: C# Generics - Part 3: Methods & Delegates.

Generics are extremely useful in consolidating code. In this demo, we combine 2 methods into a single one by adding a generic type parameter. This allows the method to work with a variety of types rather than being specialized for a single interface or class.

The series will continue with upcoming videos on nested generics and generic constraints.

C# Generics (Playlist)
Happy Coding!

Monday, June 9, 2014

Recognizing Higher-Order Functions in C#

I've been working more and more with functional programming in one form or another. This started a while back. My primary goal has been to look for ways to bring functional concepts into my current main language (which happens to be C#). What I have found is that I have been using functional concepts rather naturally -- as mentioned when I talked about LINQ and the Functional Approach.

So, here's another revelation: I've been using higher-order functions without realizing it.

What is a Higher Order Function?
The concept of a higher-order function is quite simple, but can also be a bit confusing:
A higher-order function is a function that takes a function as a parameter.
We're used to passing objects as parameters. Sometimes they are simple objects like an integer or a string. Sometimes they are complex objects like collections or custom classes.

But we can also pass functions as parameters. This is done using delegates or lambda expressions. Let's take a look at some examples.

Injecting Behavior with Delegates
Delegates are an important part of the C# language. And they are important to understand when looking at LINQ and lambda expressions (two of my favorite things in C#). In my presentation, "Get Func<>-y: Delegates in .NET", I show how to use delegates to inject functionality into a class.

Here's the class:


Let's take a closer look at the ToString method:


This is a function that takes another function as a parameter (Func<Person, string>). That makes this a higher-order function.

With this method in place, we can choose exactly what we want the ToString method to do when we execute it. One of the easiest things to do is use a lambda expression to represent the parameter, so that's what I normally do. Here's the code that uses this method:


The first method call is to the ToString function that takes no parameters. We just have this here for reference. But all of the other calls use the ToString method that takes a function as a parameter.

We won't go into the details of how delegates and Func<T> work; that's covered in the presentation materials. The short version is that our parameter type is Func<Person, string>. What this means is that our parameter needs to be a function that takes a "Person" as a parameter and returns a "string".

So, that's what each of these do. The "p" parameter of the lambda expression represents the current "Person" object. Then the body of the lambda expression performs the work to return a string. The first example simply calls the no-parameter ToString method. But from there, we take a little more control.

In one method, we output the LastName property in upper case. In another, we output the FirstName property as lower case. And in another, we use a "LastName comma FirstName" format.

And here's out output:


Why do we do this? Several reasons go hand-in-hand. The Single Responsibility Principle (the S in the SOLID principles) tells us that our class should only have one reason to change. With regard to our "Person" class, its primary responsibility should not be formatting output strings. So, we moved that responsibility out of the class so someone else can be responsible for it.

We also have the Open Close Principle (the O in the SOLID principles) that tells us that a class should be open to extension but closed to modification. We can add custom string outputs to the Person class (extending it) without making any changes to the class itself.

And bringing things back around, a higher-order function (ToString(Func<Person, string>)) makes this possible.

LINQ and Where
I love LINQ. It's one of my favorite tools. And I also love lambda expressions. In my presentation "Learn to Love Lambdas", I show plenty of both.

And I've recently put the pieces together that LINQ methods are good examples of higher-order functions. Let's specifically look at "Where". First, here's the declaration (from MSDN):


This shows us that "Where" takes a "Func<TSource, bool>" as a parameter. This is a delegate (which is a function), meaning that Where is a higher-order function. We won't go into all the other details of this declaration (like the extension method syntax or the generic types); these are covered in the presentation.

But let's look at the Func<TSource, bool> parameter. Like our other example, this needs to be a function that takes a TSource as a parameter (where TSource is simply the type of the objects in our collection that we're working with) and returns a true/false value.

We have a simple example of filtering with "Where" using a text box. Here's the UI:


And here's the code that uses this:


In this method, "data" is a collection of Person objects (similar to the Person class above). This code checks to see if the Name Filter checkbox is checked. If so, then it puts a Where condition on our data. And just like above, "p" represents our Person object. And we can see the comparison of the FirstName property of our Person to whatever is in the text box. This gives us a true/false value.

Here's the resulting output:


This really shows us the usefulness of a higher-order function. The "Where" function lets us pass in whatever functionality we want to determine which items we want to include in the output and which items we want to exclude from the output.

Now, "Where" is much more complicated than the "ToString" method that we showed above. "ToString" simply ran whatever function was passed in. But "Where" does quite a bit of other things. It's involved in iterating through a sequence of some sort (IEnumerable). And it does this in a lazy way -- it only returns items as we ask for them. So, there's a lot more going on behind the scenes than simply running the function that we pass as a parameter. But that function plays an important role.

As a side note, this application has a lot of code-behind (since I want to concentrate on LINQ and lambdas during the presentation and not get mired into the application too deeply). But I've also created a version that uses a view model to separate the UI from the presentation logic (also included in the "Learn to Love Lambdas" materials).

Here's what the code from the view model looks like for the name filter:


We can see that this is very similar to the previous code. The primary difference is that it does not interact directly with UI elements. It uses properties instead. So, instead of looking at the state of the "NameFilterCheckBox", it looks at the "NameFilterChecked" property on the view model (which is databound to the checkbox). And instead of looking at the "NameTextBox" UI element, it looks at the "nameFilterValue" field on the view model (which again is set through databinding to the text box in the UI).

Why Do I Care?
So, I haven't shown any new code here. This is all code that I've been presenting for several years and based on real applications that I've built.
Is knowing that these are higher-order functions really important?
The answer is YES. Now that I recognize these as higher-order functions, I can start to analyze them in that context. Higher-order functions have certain advantages, such as making the Strategy pattern easier to implement. And there are certain situations where we want to use higher-order functions, such as where we have similar functionality but we want to abstract out some of the details.

Now I can start to use these constructs more intentionally in my code. When I think about needing the Strategy pattern or I find similar functionality that can be combined, I can remember how higher-order functions can help with these.

So, even though I've been a fan of delegates, lambda expressions, and LINQ for a long time. I've been able to add another label to them: higher-order functions. It's now a new tool in my toolbox. I can learn the advantages and disadvantages of them. And I can better recognize where I should be using them.

And this is why we want to keep learning.

Happy Coding!

Monday, January 6, 2014

Improving Reflection Performance with Delegates

Reflection is an extremely powerful tool. But one of the drawbacks is performance. In my presentations on Reflection, we look at an application that shows the speed differences between calling methods directly and calling them with Reflection (live presentation on my website; video presentation on Pluralsight).

Now, the point of this application is to show that dynamically invoking a method through reflection is 30 times slower than making a direct method call. This is to encourage us to make sure we only use reflection when we actually need it. But if we do need it, there are ways to improve the performance that I don't talk about in the presentation. Instead of doing dynamic invocation directly, we can use a delegate to improve performance.

The sample code is available here: http://www.jeremybytes.com/Downloads/ReflectionWithDelegates.zip.

Baseline Speed
The sample application shows 4 different ways to call a method (as opposed to the 2 methods shown in the original presentation sample).

Here's the code for the direct method call:


Most of this code is boiler-plate to get the metrics for the UI -- and I use the word "metrics" here very loosely. This code performs the loop 10,000,000 times (which is a lot). That's how many times we need to do this so that we can get some human-noticeable times. And this just gives us a general idea. When we run this code, the computer is doing other stuff (background operations, UI updates, network polling, etc.), so the exact numbers will vary.

This important bits of the above method are the first line (where we create a new List object) and the line inside the "for" loop (where we add the indexer to the list).

When running on my machine (a dual-core i7), we get the following result:


Dynamic Invocation with Reflection
When we try the same functionality using reflection, we get a much different result. Here's the code:


This code is a little bit different. We still create the new List variable. But then, we use reflection to execute the "Add" method. To do this, we get a Type object based on List<int>. Then we call "GetMethod" which gives us back an MethodInfo object.

Then inside the loop, we call Invoke on the MethodInfo object. The parameters look a bit strange for this method. The first parameter is the instance we can to call the method on -- in this case, it is the "list" variable that we created at the top. The second parameter is an object array for the method parameters. Since we need to pass in a single parameter (an integer), we create an object array with a single value.

The result of this method call is the same as the method in the first example -- we add 10,000,000 items to a List object.

The performance is significantly different:


Instead of 127 milliseconds, we get 3.5 seconds! That's around 30 times longer.

Using an Interface
The recommendation in the Practical Reflection presentation is to use Reflection to load and instantiate an object (to give us the flexibility of run-time loading), but then cast the object to a known interface in order to call the method. This gives us the best of both worlds.

Here's that code:


At the top of this method, we get a Type object based on List<int>, and then we use the Activator class to create an instance of that type. Notice that our variable ("list") is an interface type (IList<int>) rather than a concrete type.

Because of this, even though we create the object dynamically, we can call the "Add" method just like we would on a normal object. (And we see this inside the "for" loop.)

The result is that we do not get a performance hit. It runs at the same speed as a direct method call:


Reflection with a Delegate
But there is another option as well. If we absolutely need to use Reflection to dynamically call a method multiple times, we can use a delegate to improve the performance.

Here's the code for that:


This code is a bit more complicated. Notice at the very top (outside of our button click handler), we have a definition of a delegate ("ListAddDelegate"). Notice the signature for this delegate. The first parameter is "List<int>" -- this is the instance of the list that the "Add" method is called on. The second parameter is the parameter for the "Add" method -- in this case, an integer. The delegate returns void because List<T>.Add (the method we want to call) returns void.

The first 3 lines of the button click handler match the reflection method. We create an instance of a List<int>, get a Type variable, and then use GetMethod to get a MethodInfo object.

But then we create a delegate instance. We use "Delegate.CreateDelegate" to create a delegate object based on our MethodInfo object. The first parameter is the Type of the delegate we want (our custom ListAddDelegate), and the second parameter is the MethodInfo object (the "addMethod" that we got above). Then we cast this whole thing to a ListAddDelegate.

Inside our "for" loop, we simply invoke our custom delegate by calling "addDelegate" with the 2 parameters (the List<int> instance and the integer that we want to "Add").

The result is much better performance:


This time is inline with the direct method call and the interface method call.

Here are all of the results together:


Wrap Up
The point of the original speed comparison is to show that using Reflection to call a method is 30 times slower than making a direct call. But if we do find that we need reflection to dynamically call a method multiple times, we do have the option of creating a delegate to handle the method calls.

There are several ways to come up with similar answers. As developers, we should be used to this. What we need to do is weigh the pros and cons of each approach in the context of our own application -- keeping in mind that we want to balance flexibility and performance.

Happy Coding!

Wednesday, March 13, 2013

More Delegate Exception Handling

I was speaking about Delegates at a user group a couple weeks ago and decided it was time to dive a little bit deeper into exception handling with Multi-Cast Delegates.  As a reminder about how multi-cast delegates work (and what happens if one of the methods throws an exception), check out my previous article: Exceptions in Multi-Cast Delegates.

Standard Behavior
As a quick review, all delegates in .NET are multi-cast delegates, meaning that multiple methods can be assigned to a single delegate.  When that delegate is invoked, all of the methods get run synchronously in the order that they were assigned.

Here are the delegate assignments that we were looking at before:

act += p => Console.WriteLine(p.Average(r => r.Rating).ToString());
act += p => { throw new Exception("Error Here"); };
act += p => Console.WriteLine(p.Min(s => s.StartDate));

When the delegate is invoked normally, the execution stops with the exception in the second method.  The third method never gets run.  (Check the previous article for details.)

The Issue
The main issue is that we are rarely on "both sides" of the delegate.  Usually we are either creating methods to assign to a delegate (to hook into an existing framework or API), or we are creating an API with a delegate for other people to use.

Think of it from this point of view: Let's assume that we have a publish/subscribe scenario (after all, events are just special kinds of delegates).  In that case, we have the publisher (the API providing the delegate to which we can assign methods) and the subscribers (the methods that are assigned).

If we are creating subscriber methods, then the solution is easy.  We just need to make sure that we don't let any unhandled exception escape our method.  If our code is not working correctly, then we need to trap the error and make sure that it doesn't impact any other subscribers.

But things are a little more complicated if we are the publisher.  As we saw in the previous examples, if there is a misbehaving subscriber, then other subscribers may be impacted.  We need to avoid this.  If we are responsible for the API, then we need to ensure that we notify every subscriber, regardless of whether they are behaving or not.

A More Robust Solution
We've already seen that the code we had previously just won't cut it:

try
{
    act(people);
}
catch (Exception ex)
{
    Console.WriteLine("Caught Exception: {0}", ex.Message);
}

To fix this, we can dig a little deeper into the delegate itself.  It turns out that all delegates have a method called "GetInvocationList()".  This will give us a collection of all of the methods that are assigned to the delegate (the return is technically an array of Delegate objects).  If there are no methods, then the list will be empty; otherwise, it will have all of the methods assigned.  This gives us a chance to handle things a little more manually.

foreach (var actDelegate in act.GetInvocationList())
{
    try
    {
        actDelegate.Method.Invoke(this, new object[] { people });
    }
    catch
    {
        Console.WriteLine("Error in delegate method.");
    }
}

Let's quickly walk this code.  First we call GetInvocationList() on our delegate and then "foreach" through it. As noted above, each item (actDelegate) will be a System.Delegate object.

Now, inside the loop, we can access each method individually.  The Delegate has a Method property that gives us a MethodInfo object.  MethodInfo has an Invoke method that allows us to run the delegate method.  The syntax here looks a bit odd.  The first parameter is the object on which to invoke the method.  In our case, we use "this" because our delegate exists in the class instance that we are in.

The next parameter is an object array with all of the parameters that will be passed to the method being invoked.  In our case, we have a single parameter (List<Person>).  So, we just have to create a new object array with that parameter as a member.

This seems like a lot of work, but because we are invoking each method individually, we can wrap each invocation in a try/catch block (which is exactly what we did).  Now, if a method misbehaves, we simply catch the exception and move on to the next one in the list.

If we were to use our sample assignments above, we get the following output:

6.42857142857143
Error in delegate method.
10/17/1975 12:00:00 AM

So, we've successfully coded around a misbehaving method and ensured that all of the methods assigned to our delegate are run.

Is This Really Necessary?
The question on the top of your mind is "Is this really necessary?"  After all, mutli-cast delegates are designed to allow us to make a single invocation that runs all of the assigned methods.  Should we add this much complexity?

The answer is "It depends."  (You've probably noticed that "it depends" is my standard answer.)  If I were writing a delegate where I control both ends (for example, I'm writing both the publisher and the subscribers), then I probably wouldn't code this way.  I would put more effort into ensuring that the subscribers behave appropriately and would not throw an unhandled exception.

However, if I were creating an API for general distribution, I would be much more protective about my delegate invocations.  In that scenario, we need to make sure that a single bad input cannot bring down the system.

Wrap Up
Delegates are extremely powerful and useful -- multi-cast delegates even more so.  They can help us make our system extensible without requiring modification.  They can offer "hooks" for other developers to run their own code.  They give us a way to do pseudo-functional programming in our object-oriented C# environment.

We need to be aware of what can go wrong when we add these tools.  As we've seen, it is not difficult to handle exceptions (either in the methods or in the delegate invocation).  When we make sure that we have our bases covered, then we can minimize unpleasant surprises in our system.

Happy Coding!

Sunday, October 21, 2012

Unit Testing: A Journey

In the last article (Abstraction: The Goldilocks Principle), we took a look at some steps for determining the right level of abstraction for an application.  We skipped a big reason why we might want to add abstractions to our code: testability.  Some developers say that unit testing is optional (I used to be in this camp).  But most developers agree that in order to be a true professional, we must unit test our code (and this is where I am now).

But this leads us to a question: Should we modify our perfectly good code in order to make it easily testable?  I'll approach this from another direction: one of the qualities of "good code" is code that is easily testable.

We'll loop back to why I take this approach in just a moment.  First, I want to describe my personal journey with unit testing.

A Rocky Start
Several years back, I didn't think that I needed unit testing.  I was working on a very agile team of developers (not formally "big A" Agile, but we self-organized and followed most of the Agile principles).  We had a very good relationship with our end users, we had a tight development cycle (which would naturally vary depending on the size of the application), we had a good deployment system, and we had a quick turnaround on fixes after an application was deployed.  With a small team, we supported a large number of applications (12 developers with 100 applications) that covered every line of business in the company.  In short, we were [expletive deleted] good.

We weren't using unit testing.  And quite honestly, we didn't really feel like we were missing anything by not having it.  But companies reorganize (like they often do), and our team became part of a larger organization of five combined teams.  Some of these other teams did not have the same level of productivity that we had. Someone had the idea that if we all did unit testing, then our code would get instantly better.

So, I had a knee-jerk reaction (I had a lot of those in the past; I've mellowed a lot since then).  The problem is that unit testing does not make bad code into good code.  Unit testing was being proposed as a "silver bullet".  So, I fought against it -- not because unit testing is a bad idea, but because it was presented as a cure-all.

Warming Up
After I have a knee-jerk reaction, my next step is to research the topic to see if I can support my position.  And my position was not that unit testing was bad (I knew that unit testing was a good idea); my position was that unit testing does not instantly make bad code into good code.  So, I started reading.  One of the books I read was The Art of Unit Testing by Roy Osherove.  This is an interesting read, but the book is not designed to sell you on the topic of unit testing; it is designed to show you different techniques and assumes that you have already bought into the benefits of unit testing.

Not a Silver Bullet
I pulled passages out of the book that confirmed my position: that if you have developers who are writing bad code, then unit testing will not fix that.  Even worse, it is very easy to write bad unit tests (that pass) that give you the false impression that the code is working as intended.

But Good Practice
On a personal basis, I was looking into unit testing to see if it was a tool that I wanted to add to my tool box.  I had heard quite a few really smart developers talk about unit testing and Test Driven Development (TDD), so I knew that it was something that I wanted to explore further.

TDD is a topic that really intrigued me.  It sounded really good, but I was skeptical about how practical it was to follow TDD in a complex application -- especially one that is using a business object framework or application framework that supplies a lot of the plumbing code.

Actual Unit Testing
I've since moved on and have used unit testing on several projects.  Now that I am out of the environment that caused the knee-jerk reaction, I fully embrace unit testing as part of my development activities.  And I have to say that I see the benefits frequently.

Unit Tests have helped me to manage a code base with complex business rules.  I have several hundred tests that I run frequently.  As I refactor code (break up methods and classes; rearrange abstractions; inject new dependencies), I can make sure that I didn't alter the core functionality of my code.  A quick "Run Tests" shows that my refactoring did not break anything.  When I add new functionality, I can quickly make sure that I don't break any existing functionality.

And there are times when I do break existing functionality.  But when I do, I get immediate feedback; I'm not waiting for a tester to find a bug in a feature that I've already checked off.  Sometimes, the tests themselves are broken and need to be fixed (for example, a new dependency was introduced in the production code that the test code is not aware of).

I'm not quite at TDD yet, but I can feel myself getting very close.  There are a few times that I've been writing unit tests for a function that I just added.  As I'm writing out the tests, I go through several test cases and sometimes come across a scenario that I did not code for.  In that case, I'll go ahead and write the test (knowing that it will fail), and then go fix the code.  So, I've got little bits of TDD poking through my unit testing process.  But since I'm writing the code first, I do end up with some areas that are difficult to unit test.  I usually end up refactoring these areas into something more testable.  With a test-first approach, I might have gotten it "right" the first time.

Over the next couple weeks, I'll be diving into a personal project where I'm going to use TDD to see how it will work in the types of apps that I normally build.

One thing to note: my original position has not changed.  Unit Testing is a wonderful tool, and I believe that all developers should be unit testing at some level (hopefully, a level that covers the majority of the code).  But unit testing will not suddenly fix broken code nor will it fix a broken development process.

TDD
Now that I've seen the benefits of unit testing firsthand, I've become a big proponent of it.  And even though I didn't see the need for it several years back, I look back now and see how it could have been useful in those projects.  This would include everything from verifying that automated messages are sent out at the right times to ensuring that business rule parameters are applied properly to verifying that a "cleaning" procedure on user data was running properly.  With these types of tests in place, I could have made feature changes with greater confidence.

Advantages
When a developer is using TDD, he/she takes the Red-Green-Refactor approach.  There are plenty of books and articles that describe TDD, so I won't go into the details.  Here's the short version: The first step (Red) is to write a failing test based on a function that is required in the application.  The next step (Green) is to write just enough code for the test to pass.  The last step (Refactor) comes once you're a bit further into the process, but it is the time to re-arrange and/or abstract the code so that the pieces fit together.

The idea is that we only write enough code to meet the functionality of our application (and no more).  This gets us used to writing small units of code.  And when we start composing these small units of code into larger components, we need to maintain the testability (to make sure our tests keep working).  This encourages us to stay away from tight coupling and putting in abstraction layers as we need them (and not before).  In addition, we'll be more likely to write small classes that work in isolation.  And when we do need to compose the classes, we can more easily adhere to the S.O.L.I.D. principles.

Back to the Question
So this brings us back to the question we asked at the beginning: Should we modify our perfectly good code in order to make it easily testable?  And the answer is that if we write our tests first, then well-abstracted testable code will be the natural result.

I've done quite a bit of reading and other study of Unit Testing.  One of the things that I didn't like about some of the approaches is when someone "cracked open" a class in order to test it.  Because the unit they wanted to test was inaccessible (perhaps due to a "protected" access modifier), they wrote a test class that wrapped the code in order to make those members visible.  I never liked the idea of writing test classes that wrapped the production classes -- this means that you aren't really testing your production code.

However, if we take the approach of test-first development (with TDD or another methodology), then the classes we build will be inherently testable.  In addition, if a member needs to be injected or exposed for testing, it grows more organically with the corresponding tests.

Abstractions
And back to the last article about abstractions: if we approach our code from the test side, we will add abstractions naturally as we need them.  If we need to compose two objects, we can use interfaces to ensure loose-coupling and make it easier to mock dependencies in our tests.  If we find that we need to inject a method from another class, we can use delegates (and maybe the Strategy pattern) to keep the separation that we need to maintain our tests.

Wrap Up
Whole books have been written on unit testing (by folks with much more experience than I have).  The goal here was to describe my personal journey toward making unit tests a part of my regular coding activities.  I fought hard against it in one environment; this made me study hard so that I understood the domain; this led to a better understanding of the techniques and pitfalls involved.  There are three or four key areas that I have changed my thinking on over the years (one of which is the necessity of unit testing).  When I change my mind on a topic, it's usually due to a deep-dive investigation and much thought.  Unit testing was no different.

You may be working in a group that is not currently unit testing.  You may also think that you are doing okay without it.  You may even think that it will take more time to implement.  I've been there.  Start looking at the cost/benefit studies that have been done on unit testing.  The reality is that overall development time is reduced -- remember, development is not simply slapping together new code; it is also maintenance and bug-hunting.  I wish that I had done this much sooner; I know that my past code could have benefited from it.

My journey is not yet complete; it will continue.  And I expect that I will be making the transition to TDD for my own projects very soon. 

Maybe the other developers on your team don't see the benefits of unit testing, and maybe your manager sees it as an extension to the timeline.  It's easy to just go along with the group on these things.  But at some point, if we truly want to excel as developers, we need to stop being followers and start being leaders.

Happy Coding!

Saturday, October 20, 2012

Abstraction: The Goldilocks Principle

Abstractions are an important part of object-oriented programming.  One of the primary principles is to program to an abstraction rather than a concrete type.  But that leads to a question: What is the right level of abstraction for our applications?  If we have too much abstraction, then our applications can become difficult to understand and maintain.  If we have too little abstraction, then our applications can become difficult to understand and maintain.  This means that there is some "sweet spot" right in the middle.  We'll call this the Goldilocks level of abstraction: "Just Right."

So, what is the right level?  Unfortunately, there are no hard-and-fast rules that are appropriate for all development scenarios.  Like so many other decisions that we have to make in software development, the correct answer is "it depends."  No one really likes this answer (especially when you're just getting started and are looking for guidance), but it's the reality of our field.

Here are a few steps that we can use to get started.

Step 1: Know Your Tools
The first step to figuring out what abstractions to use is to understand what types of abstractions are available.  This is what I focus on in my technical presentations.  I speak about delegates, design patterns, interfaces, generics, and dependency injection (among other things).  You can get information on these from my website: http://www.jeremybytes.com/Demos.aspx.  The goal of these presentations is to provide an overview of the technologies and how they are used.  This includes examples such as how to use delegates to implement the Strategy pattern or how to use interfaces with the Repository and Decorator patterns.

We need to understand our tools before we can use them.  I try to show these technologies in such a way that if we run into them in someone else's code, they don't just look like magic incantations.  If we can start looking at other people's code, we can get a better feel for how these tools are used in the real world.

A while back, I wrote an article about this: Design Patterns: Understand Your Tools.  Although that pertains specifically to design patterns, the principle extends to all of the tools we use.  We need to know the benefits and limitations to everything in our toolbox.  Only then can we make an informed choice.

I remember seeing a woodworking show on television where the host used only a router (a carpentry router, not a network router).  He showed interesting and unintended uses for the router as he used it as a cutting tool and a shaping tool and a sanding tool.  He pushed the tool to its limits.  But at the same time, he was limiting himself.  He could use it as a cutting tool, but not as effectively as a band saw or a jigsaw or a table saw.  I understand why this may be appealing: power tools are expensive.  But in the software world, many of the "tools" that we use are simply ideas (such as design patterns or delegates or interfaces).  There isn't a monetary investment required, but we do need to make a time investment to learn them.

Step 2: Know Your Environment
The next step is to understand your environment.  Whether we are working for a company writing business applications, doing custom builds for customers, or writing shrink-wrap software, this means that we need to understand our users and the system requirements.  We need to know what things are likely to change and which are not.

As an example, I worked for many years building line-of-business applications for a company that used Microsoft SQL Server.  At that company, we always used SQL Server.  Out of the 20 or so applications that I worked on, the data store was SQL Server.  Because of this, we did not spend time abstracting the data access code so that it could easily use a different data store.  Note: we did have proper layering and isolation of the data access code (meaning, all of our database calls were isolated to specific data access methods in a specific layer of the application).

On the other hand, I worked on several applications that used business rules for processing data.  These rules were volatile and would change frequently.  Because of this, we created rule interfaces that made it very easy to plug-in new rule types.

I should mention that these applications could have benefited from abstraction of the database layer to facilitate unit testing.  We were not doing unit testing.  In my next article, I will talk more about unit testing (and my particular history with it), and why it really is something we should all be doing.

Step 3: Learn the Smells
A common term that we hear in the developer community is "code smells". This basically comes with experience.  As a developer, you look at a bit of code and something doesn't "smell" right -- it just feels off. Sometimes you can't put your finger on something specific; there's just something that makes you uncomfortable.

There are a couple of ways to learn code smells.  The preferred way is through mentorship.  Find a developer with more experience than you and learn from him/her.  As a young developer, I had access to some really smart people on my development team.  And by listening to them, I saved myself a lot of pain over the years.  If you can learn from someone else, then be sure to take advantage of it.

The less preferred (but very effective) way of learning code smells is through trial and error.  I had plenty of this as a young developer as well.  I took approaches to applications that I later regretted.  And in that environment, I got to live with that regret -- whenever we released a piece of software, we also became primary support for that software.  This is a great way to encourage developers to produce highly stable code that is really "done" before release.  While these applications were fully functional from a user standpoint, they were more difficult to maintain and add new features than I would have liked.  But that's another reality of software development: constant learning.  If we don't look at code that we wrote six months ago and say "What was I thinking?", then we probably haven't learned anything in the meantime.

Step 4: Abstract as You Need It
I've been burned by poorly designed applications in the past -- abstractions that added complexity to the application without very much (if any) benefit.  As a result, my initial reaction is to lean toward low-abstraction as an initial state.  I was happy to come across the advice to "add abstraction as you need it".  This is an extremely good approach if you don't (yet) know the environment or what things are likely to change.

As an example, let's go back to database abstractions.  It turns out that while working at the company that used SQL Server, I had an application that needed to convert from SQL Server to Oracle.  The Oracle database was part of a third-party vendor product.  For this application, I added a fully-abstracted repository that was able to talk to either SQL Server or the Oracle database.  But I just did this for one application when I needed it.

Too Much Abstraction
As mentioned above, too much abstraction can make an application difficult to understand and maintain.  I encountered an application that had a very high level of abstraction.  There were new objects at each layer (even if the object had exactly the same properties as one in another layer).  The result of this abstraction meant that if someone wanted to add a new field to the UI (and have it stored in the database), the developer would need to modify 17 different code files.  In addition, much of the application was wired-up at runtime (rather than compile time), meaning that if you missed a change to a file, you didn't find out about it until you got a runtime error.  And since the files were extremely decoupled, it was very difficult to hook up the debugger to the appropriate assemblies.

Too Little Abstraction
At the other end of the spectrum, too little abstraction can make an application difficult to understand and maintain.  Another application that I encountered had 2600 lines of code in a single method.  It was almost impossible to follow the logic (lots of nested if/else conditions in big blocks of code).  And figuring out the proper place to make a change was nearly impossible.

"Just Right" Abstraction
My biggest concern as a developer is finding the right balance -- the Goldilocks Principle: not too much, not too little, but "just right".  I've been programming professionally for 12 years now, so I've had the benefit of seeing some really good code and some really bad code (as well as writing some really good code and some really bad code).

Depending on what kind of development work we do, we can end up spending a lot of time supporting and maintaining someone else's code.  When I'm writing code, I try to think of the person who will be coming after me.  And I ask myself a few key questions.  Will this abstraction make sense to someone else?  Will this abstraction make the code easier or harder to maintain?  How does this fit in with the approach used in the rest of this application?  If you are working in a team environment, don't be afraid to grab another developer and talk through a couple of different options.  Having another perspective can make the decision a lot easier.

The best piece of advice I've heard that helps me write maintainable code: Always assume that the person who has to maintain your code is a homicidal maniac who knows where you live.

One other area that will impact how much abstraction you add to your code is unit testing.  Abstraction often helps us isolate code so that we can make more practical tests.  I'll be putting down my experiences and thoughts regarding unit testing in the next article.  Until then...

Happy Coding!

Tuesday, September 18, 2012

Session Spotlight - Learn to Love Lambdas

I'll be speaking at SoCal Code Camp (Los Angeles) on October 13 & 14. If you're not signed up yet, head over to the website and let them know that you're coming: http://www.socalcodecamp.com/.

Back by popular demand: Learn to Love Lambdas

Lambda Expressions
Lambda expressions are a very powerful tool that can add elegance to our code.  The problem is that they look like a secret code the first time you see them.  You've probably come across something that looks like this:


It looks daunting, but it's fairly easy to learn.  The lambda expression that we have here is just an anonymous delegate.  If we were to use a more verbose syntax, we get something like this:


We are probably a bit more comfortable with this syntax.  Here, we can tell that we're hooking up some sort of event handler, and it has standard event handler arguments: object and some type of EventArgs.  Inside the method body, we are assigning the Result property of the EventArgs to display in a list box.

This anonymous delegate is equivalent to the lambda expression above.  To create the lambda expression, we just replace the "delegate" keyword (before the parameters) with the "goes to" operator (=>) after the parameters.  The parameter types are optional, so we can get rid of those.  Also, since the method body only has one statement, we can remove the curly braces.  This leaves us with a compact and readable syntax.

Delegates abound in the .NET framework (and in add-on frameworks like the Prism library).  Whenever we have LINQ extension methods, event handlers, callbacks, or tasks, we can use lambda expressions to add compact blocks of code right where they are most useful.  And in some instances (like when working with the Prism variants of RaisePropertyChanged) we can make our code more conducive to refactoring by replacing strings with compiler-checked pieces of code.

Once you get used to lambda expressions, they are extremely readable.  In this session, we'll learn the lambda syntax, use lambdas for asynchronous callbacks, see a really cool feature that makes code safer, and see how lambdas were designed to be used extensively in LINQ.  If you'd like to Learn to Love Lambdas, be sure to stop by my session at a code camp near you.

In addition to the SoCal Code Camp on Oct 13/14, I'll also be presenting this session at the Silicon Valley Code Camp on Oct 6/7 (this session is scheduled for 2:45 p.m. Sunday afternoon -- last session of the day).

Also be sure to check out the walkthrough and code samples here: Jeremy Bytes.

Hope to see you at an upcoming event.

Happy Coding!