Showing posts with label Extension Method. Show all posts
Showing posts with label Extension Method. Show all posts

Tuesday, February 24, 2015

The LINQ OfType<TResult> Method: Cast or Filter?

So, we're continuing a bit more with LINQ questions that I've had come up recently. Last time, we looked at the difference between using a LINQ method with a predicate or without. Today, we move on to another useful filtering tool: OfType<TResult>.

I use this method in one of my samples and have had some questions come up:
When you use OfType, does it do a cast? What happens if the type doesn't match?
Let's take a closer look at OfType, what it really does, and where I find it useful.

OfType in Action
Last time, we looked at the SingleOrDefault method, and we used the following sample code that saves off a selected item in a list box and then re-assigns it after the list box is repopulated:

Saving the Selected Item
Re-assigning the Selection

Notice that we're using "OfType<Person>()" on the contents of the list box. This is because the "Items" property is not strongly typed.

Let's look at the signature of "OfType":


This is an extension method (just like every other LINQ method). And if we take a closer look, we see this takes an "IEnumerable" as a parameter. Notice that the parameter does *not* have a generic type parameter. So this is an IEnumerable that contains "object" elements. The return value is an IEnumerable *with* a generic type parameter. So the result is strongly typed.

Cast or Filter?
If we just look at the method signature, we might be inclined to believe that this method is doing a cast -- coercing the contained items from "object" to the type of our choice. But this is not what is happening.
OfType<TResult>() is a Filter (not a cast).
The reality is that the "OfType" method is simply a filter, just like many other LINQ methods.

No Exceptions
This also means that if the type does not match the object in the IEnumerable, it does *not* throw an exception. Instead, it simply does not return that record.

A Useful Tool
I find the "OfType<TResult>" method to be a useful little tool when I want to convert an object-based collection into a strongly-typed collection. (I'm using "collection" in the general sense here. Technically, we're dealing with iterators (IEnumerable), and these do not need to represent a collection of objects; they could just a easily be a sequence that is generated on-the-fly as the elements are requested.)

In our case, I want to use LINQ methods against the "Items" property of a WPF list box. If we look at the "Items" property, we see that is an "ItemCollection":


And if we look at "ItemCollection", we see that it implements "IEnumerable" (which represents items of type "object"), but not "IEnumerable<T>" (a strongly-typed enumeration):


Pretty much all of the LINQ methods work on "IEnumerable<T>", like we saw with our "SingleOrDefault" method last time:


This means that we need to turn our "IEnumerable" into a strongly-typed "IEnumerable<T>". And that's exactly what "OfType<TResult>" does for us.

Where I Use OfType<TResult>
I find myself using the "OfType" method when dealing with UI controls, like in the examples we saw today. This is because the collection controls are designed to handle pretty much anything we can throw at them -- and that's one of the really cool things about XAML controls and XAML data binding.

But this also means that if we need to pull data out of a UI control, we need to cast it in order to work with it more easily. And that's exactly what "OfType" lets us do.

Again, this isn't doing a cast, but the outcome is pretty much the same. We put an IEnumerable of object in one end and get a strongly-typed IEnumerable<T> out the other end.

When we're using data binding, we often don't need to worry about this. If we have a strongly-typed collection in our view model, we can data bind it to the UI control with no problem at all. And the data binding infrastructure takes care of any type changes for us.

But there are times when we need to pull things out manually in order to work with them. In those situations, the "OfType" method makes things much easier.

Wrap Up
I tell people all the time that they need to take a look at all of the LINQ extension methods that are available to us. Go take another look right now: IEnumerable<T> Extension Methods. This list contains lots of useful methods. And there are a few gems in there that you may not know exist.

LINQ is one of my favorite things. That's probably because I deal with collections of in-memory objects all the time. I get data from a data source, and then I need to manipulate it a little bit for the UI. LINQ lets me do that very easily -- and the end result is happier users.

Next time, we'll take a look at the "Join" method. This is a little more complex, but it's not too hard to understand the parameters when we take them one at a time. So stay tuned for more on LINQ.

Happy Coding!

Monday, January 26, 2015

Fixing Problems with a (Specific) Fluent API

I'm still working on my home automation project. Recently, I've been dealing with the code that gets data for sunrise and sunset times -- and it's been getting a lot better. But in my last update to the code, I put in some extension methods so that we code using a fluent API.

I've since thought about this, and based on the problems with the current implementation, it needs to be updated. There are 2 directions we can take with this, so I created some branches and coded up both of them. After further consideration, I'll make a decision on which one will be merged back into the master branch.

The code (and articles) for this project are collected here: Rewriting a Legacy Application. The code is on GitHub: jeremybytes/house-control. And we'll be looking at several branches here.

The Problem Code
The problem code is in the FluentAPI-Original branch (we're specifically looking at the "SunriseSunsetOrg.cs" file in the "HouseControl.Sunset" project). The main idea behind this code is that we have a set of extension methods on the "string" class:


If you're not familiar with extension methods, check out Quick Byte: Extension Methods.

We're paying attention to the first parameter here (the one with the "this" keyword). Because the "GetSunsetString" takes a string and returns a string, and the "GetLocalTime" takes a string and returns a DateTime, we can write code like this (where "cacheData" is a string):


I like this syntax (and I've always liked fluent APIs such as LINQ). And this code works fine in isolation. But if we step back and take a broader look at what we've done with this code, it starts to look a little less brilliant.

Specifically, the extension methods extend the "string" class. This means that the methods really should work with *any* string that we give them. But the reality is that they only work with very specific strings: a JSON object and a date/time string.

But because these are extension methods on "string", there's nothing to stop us from using them on other string objects:


This is really bad. If we have a string that contains "Hello", we can call "GetLocalTime" on that. And the code completion in Visual Studio is almost encouraging us to do that. But it would just result in an error.

Falling into the Pit of Success
I really don't like code that lets developers get themselves into trouble so easily. When I create a library, I really want the developers to fall into the pit of success. This means that I need to remove any dangers that I can. This code is too easy to use incorrectly.

And there are really 2 directions that we can go with this. First, we can create more specific types that we use for our extension methods. Instead of using "string", we would use a custom type that contains the JSON data or the date/time data as appropriate.

The other option is to remove the extension methods (and along with it the fluent API). We'll explore both of these options.

Option #1: An Updated Fluent API
If I decide that I really like the fluent API, then we can use the code that makes the API a bit safer. This code is in the FluentAPI-Updated branch.

The extension methods have been updated to work with custom types (instead of string):


We have 2 new types -- "ResponseContentString" and "UTCTimeString" -- which are designed to hold the JSON result of our service and a string that represents a UTC time, respectively.

Notice that "GetSunriseString" and "GetSunsetString" both take a "ResponseContentString" as a parameter and return a "UTCTimeString". Then we can use that "UTCTimeString" with the "GetLocalTime" method to return the local date/time.

The custom classes themselves are pretty simple. In fact, I just added them to the top of the same "SunriseSunsetOrg.cs" file.


These just have a single property to hold a string value. But because they are custom types, we can target our methods a bit better.

When we have these in place, we can still use the same fluent syntax:


But in order to do this, we've had to change a few of our variables. Notice that the "cacheData" field is now a "ResponseContentString".

And if we look at the methods on this type, we see that they are a bit more focused:


So we see that we have "GetSunriseString" and "GetSunsetString" available to us (but not "GetLocalTime").

And if we tried to make a call on a "Hello" string (like we did above), we would not see any of our extension methods since they now operate on these custom types.

Note: As another alternative, we could move the extension methods so that they are part of the custom classes themselves. But before doing that, we need to think about whether it confuses the responsibility of each class. I could argue either way in this case. We'll stick with the separate extension methods here.

Advantages & Disadvantages
The biggest advantage to this approach is that we get to keep the fluent API. The biggest disadvantage is that we now have more custom types floating around our code.

So, we're making our code a bit more complex in order to make using the API a bit simpler. Like everything else we deal with when making decisions about our code, everything is a bit of give and take.

Now let's take a look at another option.

Option #2: Remove the Fluent API
Our other option is to get rid of the fluent API by removing the extension methods. This code is in the FluentAPI-Removed branch.

We're not removing the functionality that was in the extension methods, we're just turning them into normal methods:


These methods are now in the "SunriseSunsetOrg" class instead of the "SunriseSunsetOrgHelpers" class. And they are now just static methods. Notice that the "this" keywords have been removed from the parameters.

These have the same functionality, but we end up calling them a bit differently. Here's our calling method:


Notice that our fluent syntax is gone. Now we're calling methods with parameters and passing results as parameters to the next method. We could tighten up this code a little bit (by removing some of the intermediate variables), but it gets more difficult to read and debug.

For a look at why we may or may not want the intermediate variables, check out I Can Write That Method with One Line of Code.

Advantages  & Disadvantages
The biggest advantage to this approach is that we keep things simple. We don't add any new custom types (notice that the "cacheData" field is just a "string" like it was before).

The biggest disadvantage is that we lose the fluent syntax. Again, I like fluent APIs (where they make sense). And I'm okay with losing access to the fluent nature of the API if it's not appropriate here.

Which Would You Choose (and Why)?
I am going to merge one of these options back into the master branch of this project. So the question is, which one should I choose? And is there a good reason to choose one over the other?

The branches are all on GitHub:


I'm planning on leaving these branches in the repository even after I've merged the branch that I want. That way, the code will stay there to go along with this article.

So, check out the FluentAPI-Original branch to see the code in its problem state (with the extension methods on "string").

The FluentAPI-Updated branch has the code for Option #1 where we maintain the fluent API by adding custom types.

The FluentAPI-Removed branch has the code for Option #2 where we remove the extension methods and do not add any custom types.

[Update 01/28/2015: Based on the comments on this article, I've explored some options a little further: Reviewing Options: Building on the Experience of Other Developers.]

Wrap Up
I'll be considering the pros and cons of these options over the next few days. Neither one of these affect the operation of the application (in fact, the "problem" code is running just fine in production). But I'm using this application to experiment with different techniques. This lets me practice my skills so that I can more readily use them in other environments.

Coding practice is important, and it's something that many developers never do. When we go through exercises like this one, we think through techniques and approaches, and we find out what works well for us and what doesn't. That way, when we get into "crunch time" in a real application, we know exactly what approach will work best for us.

Happy Coding!

Wednesday, April 24, 2013

Cool Stuff: Building a DSL

Code Camp is a great place to expand your thinking.  Whenever I attend, I like to go to sessions on topics that I wouldn't normally seek out on my own.  I've already dedicated the day to attending, so I might as well try out some new things.  (I also go to meet other developers -- find out what works, what doesn't work, and what's really cool.)

This past weekend during Desert Code Camp, you may have seen "MIND BLOWN" come across my Twitter feed (and if not, then you can follow me: @jeremybytes). This came from the session "Building a DSL with an OData Source".

I didn't attend this session because I had a particular interest in the topic -- I've never worked with an OData feed, and I've always thought DSLs (Domain Specific Languages) were complicated (more on this in a bit).  I attended because it was presented by a friend of mine from the dev community: Barry Stahl (blog: Cognitive Inheritance; twitter: @bsstahl).  I was amazed at what I saw.

The Scenario
Barry showed how to query the OData feed from StackOverflow.  StackOverflow is a good choice since pretty much every developer is familiar with the site.  To query the data in its "native" state (meaning, after Visual Studio has a chance to make a service proxy based on the Atom feed), the original query looks like this:


This query gets questions that were asked in the last 30 days that have at least 1 accepted answer.  There are a lot of details that you need to know to write this query.  For example, "Parent == null" means that this is a root element (meaning, a question).  And, "AcceptedAnswerId != null" means that there is at least one accepted answer.

The goal was to create a DSL that would save the developer from these details and make this query readable and discoverable.  Like this:


This version is much easier to read and hides the details of the original API.  You can get the slides and code download for this session from Barry's site: DCC 2013.1.

The Mind Blowing Realization
What was amazing about this presentation is how easy this is to implement.  I had always thought of a DSL as something complex to build.  This put it into the "you probably don't need to do this" category in my mind -- best left for the big brains who work on languages and compilers and that sort of thing.

But Barry showed that building a DSL can be exactly the opposite -- something easy and obvious.  He used a combination of helper classes and properties along with extension methods to shield the user of the DSL from the underlying details.

For example, the "Questions" property (from the FluentStack object above) wraps the "Posts where ParentID == null" part of the original query.  The other elements are similar wrappers that make the API easy to use and discoverable (through IntelliSense).

Very simple.  Extremely approachable.  Amazingly cool.

Wrap Up
I never would have thought of this approach on my own.  I still don't know if I'll end up ever working with an OData feed.  But I do know that I'll be using some of these techniques to make complex APIs easier to use.

Barry is really smart and a great presenter (plus, he's a good guy to sit around and chat with).  He travels to Code Camps around the country, so be sure to look for him at an event near you.

Code Camp is a great way to expand your horizons, learn new things, and maybe even be surprised from time to time.

Happy Coding!

Monday, January 21, 2013

Extension Methods - The Movie

So, I've created my first technical screencast: an overview of extension methods.  Now available on YouTube: http://www.youtube.com/watch?v=fKxy8Hl7Ht0.

If you'd like to see more videos, let me know the topics you're interested in (just leave a comment on this post).  If you don't want to see more, let me know that as well.  The goal is to make my blog, website, and other resources as useful as possible.

Happy Coding!

Friday, May 25, 2012

Next, Please! - A Closer Look at IEnumerable (Part 5 - Usage Tips & Wrap-up)

This is a continuation of "Next, Please! - A Closer Look at IEnumerable".  The articles in the series are collected together here: JeremyBytes - Downloads.

Last time, we took a look at the Strategy pattern and then used that pattern to create a StrategicSequence that allows us to pass in whatever algorithm we want to generate the sequence.  This gives us an class that can be extended without modifying the class directly and gives the application (client) the opportunity to select which algorithm to use.

Today, we'll explore some tips for using classes that implement IEnumerable<T> (whether they are classes we create ourselves or classes from the .NET Framework).

IEnumerable<T> Tips
As we've seen, IEnumerable<T> is a fairly simple interface that gives us access to a lot of functionality.  But, there are a number of things we should take into consideration when we decide on how to use that functionality in our applications.

Tip: Don't Modify Collection Items in a foreach Loop
This is actually a "don't ever do this" rather than a "tip".  When using a foreach loop (or using the enumerator more directly), it is very tempting to modify the items as you are iterating them.  However, this only causes problems (some more obvious than others).

First, what happens if we try to add or remove an item in a foreach loop?  Consider the following code:


The idea behind this code is that we iterate through our people collection (with a foreach loop).  If the FirstName property of the person is "John", then we want to remove that person from the collection.  Then we want to add that person object to the list box of our UI.

But we are not allowed to add or remove items from a List<T> while we are enumerating it.  This code will compile just fine, but if we try to run it, we get the following Exception:
System.InvalidOperationException: "Collection was modified; enumeration operation may not execute."
So adding and removing items is not allowed.  What about modifying items?  That's where things get a bit interesting.  Let's look at the following code:


Inside the foreach loop, we first add the "person" to the list box of our UI.  Then if the FirstName property is "John", we change it to "Test".  We would expect that we would see the "John" items in the list box (since we add thems before changing them).  But here is the output:


As you can see, "Test" is showing up in our output!  This is not the output we would expect from this code.  The strangeness is a result of trying to update a collection while we are iterating that collection.

Based on these problems, we never want to modify a collection as we are iterating it.  In most situations, it is fairly easy to come up with another solution that accomplishes our same goals by handling the modification outside of the iteration.  Note: "for" loops do not exhibit this same issue since they do not use the enumerator; this is sometimes a good solution (but not always).

Tip: Avoid Creating A Custom Class
In our samples from Part 3 and Part 4, we created classes that return a sequence of numbers.  I purposely chose this type of sequence because we could base our "MoveNext()" on a calculation of some type.  In most situations, though, there is no need to create a custom class that implements IEnumerable<T>.

As mentioned in Part 1, almost every .NET collection implements the IEnumerable interface.  This includes arrays, generic lists, linked lists, queues, stacks, and dictionaries.  Generally speaking, if you find yourself in a situation where you need an IEnumerable implementation (because you need to iterate through a set of items), you will probably also need the more advanced collection functionality that you get with one of these framework classes.

In most scenarios, we should start by looking at the .NET collection classes.  One of these classes will mostly likely fulfill our needs.

Tip: Use a Custom Class to Hide Functionality
Sometimes the .NET collections have more functionality than we want to expose in our application.  For example, let's say that we need a collection that we can iterate through, but we don't want to use "List<T>" because we don't want the collection items to be directly modifiable.

Here's an example how we can use a custom class to wrap a List<T> object and hide its functionality:


We have a custom class that implements IEnumerable<T> (so we'll get our iteration functionality).  The class contains a private list that is not visible externally.  The list gets initialized by the class constructor.

Notice the GetEnumerator() method.  Instead of implementing our own IEnumerator<T> class or using "yield return", we are simply calling the internal list's GetEnumerator() method.  This is perfectly valid.  And it makes sense to do it in this situation -- the IEnumerator is already implemented by an object in our class, so there is no reason for us to create a custom implementation.

The result of this class is that we have a list of objects that we can iterate through, but we have no way to modify the collection externally.  Note that we are also hiding the other List<T> members in the private class (such as IndexOf), but we still have access to all of the IEnumerable<T> extension methods, such as Single() and Where(), if we are searching for particular items in the collection.

Tip: Use a Custom Class to Reduce Overhead
Sometimes we don't need all of the functionality provided by a collection object.  In that case, we can create a custom class that implements IEnumerable<T> that only has the functionality that we need.  This is exactly what we did with our sequence classes: IntegerSequence, FibonacciSequence, and StrategicSequence.

We did not need any of the overhead associated with a collection since our values are calculated as we need them.  Granted, our example is a rather contrived one.  But it demonstrates that it is possible and practical to have a class that implements IEnumerable<T> without other collection-type functionality.

IEnumerable<T> Review
The last several articles have shown a lot of different aspects of IEnumerable<T>.  Let's do a quick review:

IEnumerable<T> Interface Members
We started by looking at the IEnumerable<T> and IEnumerator<T> interfaces. We saw the methods and properties (such as GetEnumerator(), Current, and MoveNext()) that are specified in each.

Iterator Pattern
The Iterator pattern is described by the Gang of Four as a way to get items one-by-one from a collection -- "Next, Please!"  The IEnumerable<T> interface describes an implementation of this pattern.

foreach Loop
We can use a "foreach" loop to iterate through the items contained in any class that implements IEnumerable<T>.  This is an easier way to interact with the class then if we were to explicitly call the GetEnumerator() method along with MoveNext() and Current.

Extension Methods
Extension methods give us a way to add functionality to a class without modifying the class directly.  From a syntactic standpoint, extension methods behave as if they are native methods of the class.

IEnumerable<T> and LINQ
LINQ (Language INtegrated Query) provides us with a myriad of extension methods on the IEnumerable<T> interface.  This gives us the ability to write queries and perform all types of functions against any class that implements IEnumerable<T>, including (but not limited to) filtering, sorting, aggregation, and grouping.

Implementing IEnumerable<T>: IntegerSequence
Our first custom implementation of IEnumerable<T> let us take a look at the members of IEnumerable<T> and IEnumerator<T>.  We saw what each member is designed for, and we used the members to create a class that returns a series of consecutive positive integers.

yield return
"yield return" provides us with shortcut syntax when implementing an enumerator.  It lets us create a method that retains its state between calls.  Using this, we can mimic a full implementation of the IEnumerator<T> class with a single method.

Implementing IEnumerable<T>: FibonacciSequence
Our second custom implementation of IEnumerable<T> was a bit more complex.  We used what we learned from the simple IntegerSequence and created a class that returns the Fibonacci sequence, where each value is the sum of the previous two values.

Strategy Pattern
The Strategy pattern is described by the Gang of Four as a way to create a set of encapsulated, interchangeable algorithms.  We took a look at the advantages of using the pattern as well as some of the negative consequences.

The StrategicSequence Class
Our final custom implementation of IEnumerable<T> let us explore the Strategy pattern in a bit more detail.  The StrategicSequence class accepts a strategy (the algorithm for calculated the sequence) as a constructor parameter.  This lets us externalize the algorithms into separate classes.  We created the IntegerStrategy, FibonacciStrategy, and SquareStrategy that implemented these algorithms.  And we saw the advantages that this gave to our particular application.

Wrap Up
In summary: IEnumerable<T> is awesome!  Okay, I might be a little too excited about an interface, but it offers us a ton of functionality with very little effort.  Implementing the interface ourselves is not that difficult, and even better, there are lots of implementations already provided for us in the .NET framework.

I find myself using the LINQ extension methods all of the time.  It's so easy to just drop in a Where() method to do a filter of a collection, or an OrderBy() to sort the list, or a Single() to pick out a specific item. And all we need to take advantage of this functionality is a class that implements IEnumerable<T> and a good understanding of lambda expressions (but we've already got that, right?).

Hopefully you are as excited about IEnumerable<T> as I am (or at least a bit more interested than you were when we started).  Learning the features included in the .NET framework lets us take advantage of extremely powerful functionality that is already there just waiting for us.

Happy Coding!

Wednesday, May 23, 2012

Next, Please! - A Closer Look at IEnumerable (Part 3 - Fibonacci Sequence)

This is a continuation of "Next, Please! - A Closer Look at IEnumerable".  The articles in the series are collected together here: JeremyBytes - Downloads.

Last time, we took a look at Extension Methods and the added functionality we get from LINQ when using classes that implement IEnumerable<T>.  Today, we'll create our own class that implements IEnumerable<T> (a couple of classes, actually).  We'll see what it takes to implement the interface, a really cool shortcut that we can use, and how we can use LINQ with our newly created classes.

Implementing IEnumerable<T>: IntegerSequence
A few articles back, we explored using the BackgroundWorker Component with MVVM.  While the article did not focus on it, our Model (the ProcessModel object) implemented the IEnumerable<T> interface.  This was so that we could use the model with a foreach loop to simulate a long-running process.

Today, we'll be creating a very similar object: the IntegerSequence.  When we use this class with a foreach loop, it will return a sequence of consecutive positive integers.  A property (NumberOfValues) will specify how many integers should be part of the sequence.  The sample code can be downloaded here: JeremyBytes - Downloads.  Note: the code download includes the sample code for this article as well as the following article, so if you open up the sample projects, you will see some items that we will discuss next time.

Project Setup
The download contains both "Starter" and "Completed" solutions.  If you open the "Starter" solution, you can follow along with the steps here.  The "Completed" solution has all of the code already in place.  Each solution contains 2 projects: SequenceLibrary contains our classes; SequenceLibrary.ConsoleApp contains a console application that we will use to view the output.  So far, both of these projects are nearly empty.  So, let's write some code!

IntegerSequence Class
We'll start by adding a new class to the SequenceLibrary project called "IntegerSequence".  (Just right-click the project, select "Add", then "Class", then type "IntegerSequence.cs" in the dialog.)

First steps, add "using System.Collections" at the top of the file (we'll see why in just a bit).  Then make the class "public" and specify that it implements "IEnumerable<int>":


Visual Studio will help us implement the interface (we've seen this previously: Updating Interface Implementation).  All we need to do is right-click on "IEnumerable", select "Implement Interface" and then "Implement Interface" again.  This will stub out the interface members for us:


This gives us the 2 members that we saw in Part 1: the generic version of GetEnumerator(), and the non-generic version of GetEnumerator().  Notice that the non-generic version (the 2nd one) uses explicit implementation of the IEnumerable (non-generic) interface.  For more information, refer to Explicit Interface Implementation.

The reason that we added "using System.Collections" is because IEnumerable (non-generic) is in this namespace.  Without this using statement, the non-generic versions of IEnumerable and IEnumerator would need to be fully qualified.

But we have a problem: GetEnumerator needs to return IEnumerator<int>.  That means that we need an class that implements this interface.  (Well, technically, there's a shortcut that we'll see a little later; let's run through the full implementation for now.)

IntegerEnumerator Class
Now we'll add the IntegerEnumerator class that will implement IEnumerator<int>,  Let's add a new class to the project: right-click the project, select "Add", then "Class", then type "IntegerEnumerator.cs" in the dialog.  Add "using System.Collections" at the top of the file; then make the class "public" and specify that it implements "IEnumerator<int>":


Then we'll run through the same steps as above to implement the interface.  I've re-arranged the methods just a little bit (to keep the 2 "Current" properties together and move the "Dispose()" method to the end):


Again, we'll see the properties and methods that we saw in Part 1.  Let's run through the logic: we need to iterate through integer values starting with 1 and ending with the total number of values.  To do this, we'll need a couple of internal fields.

Let's start by adding the fields, a constructor, and the "Current" properties:


"_numberOfValues" will tell us when to end our enumeration, and we'll initialize this with a constructor.  "_position" will hold the current position in the enumeration.

Notice that we have 2 "Current" properties: one of type "int" and one of type "object".  The "int" version returns the value of the "_position" field.  The "object" version returns the "int" version of "Current".  This makes IEnumerator<T> backward compatible with IEnumerator.  Although we could return "_position" for both calls to "Current", it's generally considered a best practice to have the non-generic version simply reference the generic version (we'll see this again with IEnumerable<T> and IEnumerable).

The MoveNext() method is where we do the work for our iterator.  Here is MoveNext() along with Reset() and Dispose():


MoveNext() increments the _position field (which defaults to 0 since it is an integer), this will have the effect of making the "Current" value one unit higher than the previous value.  As a reminder, MoveNext() needs to return true or false depending on whether it was successful.  When it hits the end of the enumeration, it needs to return false.  To accomplish this, we compare the current _position to _numberOfValues.  These would be equal for the last value since we're doing a simple integer sequence.

Reset() simply puts the _position back to its initial state.  Dispose() allows us to free any resources that we might be using.  In our case, we don't have anything that needs to be disposed, so we'll just call the Garbage Collector's SuppressFinalize() method.  (This technically isn't necessary, but it will save an extra iteration of the garbage collector.)

Now that we have a fully-implemented enumerator, we can go back to our IntegerSequence class.

Finishing IntegerSequence
As we noted initially, we need to have a NumberOfValues property.  Let's add that property and create a constructor to initialize the value.  Then we just need to implement the GetEnumerator methods:


The generic version of GetEnumerator() will create a new IntegerEnumerator, passing in the NumberOfValues property.  The non-generic version of GetEnumerator simply calls the generic version of GetEnumerator.  Just like we saw with "Current" (above), this keeps our IEnumerable<T> compatible with IEnumerable.

We now have a working implementation of IEnumerable<T>!

Using IntegerSequence
To use IntegerSequence, we'll flip over to our SequenceLibrary.ConsoleApp project.  The "Starter" project already has a reference to the SequenceLibrary project and has the SequenceLibrary namespace in the "using" section.

So, let's "new" up an IntegerSequence, run it through a foreach loop, and output the results:


And the output:


Since IntegerSequence implements IEnumerable<T>, we can use it in a foreach loop.  But, we can also use the IEnumerable<T> extension methods that we saw in Part 2.

Let's say that we only want to output the even numbers between 1 and 12.  We can accomplish this by using the "Where()" extension method to filter our results:


Note how we can simply use the "Where()" method with the sequence variable where our foreach is defined.   The lambda expression (the parameter of the Where) uses the modulo operator (%) to see if the current value (i) is evenly divisible by 2.  If so, then the number is even, and it will be included.

The Shortcut: yield return
There is a much shorter way that we can implement IEnumerable<T>: using the "yield return" statement.  "yield return" implements an enumerator and saves the current state of the method.  When the next item is asked for, then the method continues where it left off.

This sounds a little confusing, so let's look at a sample.  Back to our IntegerSequence:


Take a look at the GetEnumerator() method.  Instead of explicitly returning an IEnumerator<T>, we use the "yield return" statement.  The "while" loop has the same effect as "MoveNext" from our IntegerEnumerator class (by comparing the current position to the total number of values).  The "return ++position" statement has 2 purposes.  First, it pre-increments the position variable, then it returns that value.  Since we have the "yield" statement, the state of the position variable is preserved.

Notice that with this version, we no longer need the IntegerEnumerator class.  But, since we went through the exercise of explicitly implementing the IEnumerator<T> interface, we have a much better idea of what the "yield return" statement is actually doing.

Implementing IEnumerable<T>: FibonacciSequence
The IntegerSequence class is pretty trivial.  Since it simply returns sequential values, it could easily be replaced by a "for" loop.  So, let's take a look at something a little more complicated: implementing the Fibonacci Sequence.

The Fibonacci Sequence has the following values: 1, 1, 2, 3, 5, 8, 13, 21...

I won't go into the mathematical definition (you can look that up if you're curious).  Each number in the sequence is calculated by adding the 2 previous values.  So, 1 + 1 = 2, 1 + 2 = 3, 2 + 3 = 5, 3 + 5 = 8, and so forth.

We'll start with the explicit implementation (both IEnumerable<T> and IEnumerator<T>), then we'll switch it to use the "yield return" version.  (There's a reason for doing the full implementation first; it will lead us directly into the next article.)

FibonacciSequence Class
Just like with the IntegerSequence class, we'll create a new class (calling the file "FibonacciSequence.cs"), add "using System.Collections", stubbing out the implementation of IEnumerable<T>, adding the NumberOfValues property and the constructor.


This looks almost exactly like our IntegerSequence class.  Before we can continue, we need to create the enumerator class.

FibonacciEnumerator Class
Next, we'll create a FibonacciEnumerator class.  We'll run through the same initial steps as with the IntegerEnumerator class: create a new class, add "using System.Collections", add the IEnumerator<int> interface, and stub out the implementation:


Since calculating the Fibonacci Sequence is a bit more complicated than simply incrementing integers, we'll need a few more fields to handle our calculations:


We have "_numberOfValues" (just like before) to keep track of how many values we will enumerate.  "_position" will keep track of our current position in the sequence so that we'll know when we are done.  "_previousTotal" and "_currentTotal" will be used for our calculations.  Notice that the "Current" property returns the "_currentTotal" field.

Reset() and Dispose() are pretty straight forward:


MoveNext() is a bit more complicated:


The "if (_position == 0)" condition will handle our initial state (before we have 2 previous values to add together).  The "else" will handle all the other numbers by adding together the _currentTotal and _previousTotal (the last 2 numbers), and then updating the _previousTotal and _currentTotal to the new values.

Our return value determines whether we have completed our enumeration.  Now we can complete our FibonacciSequence.

Finishing FibonacciSequence
Now we can fill in the the GetEnumerator() methods of the FibonacciSequence class:


Using FibonacciSequence
Now, we can update the console application to use the FibonacciSequence class:


And the output:


We can use the extension methods with the FibonacciSequence as well.  We could return every other value, or only values that are divisible by 3, or any number of creative uses of the extension methods.

Error Handling
Because of the nature of the Fibonacci Sequence, we may run into some issues.  Consider what happens if we create our sequence with 50 values: "new FibonacciSequence(50)" instead of 12.  Here's the output:


It looks like we have a problem toward the end of our values.  Why do we have negative numbers?  Those should not be part of the Fibonacci Sequence.

Our problem is that we are overflowing the standard Int32 that we are using for our values.  The overflow is surfacing as the negative values (since int is signed).  And once we try to continue from there, our values are completely useless.

We'll take care of this by doing a check in our FibonacciEnumerator class.  If we have a possible overflow in the MoveNext() method, we will throw an exception:


What we do is convert the _previousTotal and _currentTotal to long integers, and then see if adding them together is greater than Int32 can hold.  If so, then we throw an exception.

This means that we need to handle this exception in our console app:


Here, we're checking for the OverflowException and printing the message to the console.  Here's the output:


So, now we have some appropriate error handling to make sure that we do not get inappropriate values.  Note: this limits the valid values of our FibonacciSequence class to 47 (before we get an overflow).  If we wanted to make this class more robust, we could update it to use "long" instead of "int".  But we'll keep this as "int" for now; this will make more sense when we look at Part 4.

FibonacciSequence with yield return
Finally, we can update the GetEnumerator() function with the "yield return" statement to eliminate the separate FibonacciEnumerator class.  This is a bit more complex than the previous implementation but still not too difficult.  Basically, we combine the MoveNext() and Current into a single method:


Now we have local variables for _previousTotal and _currentTotal.  We use a "for" loop to return the right number of values.  The rest is similar to what we had in the MoveNext() method.

Next Time
This time, we took a look at how to implement IEnumerable<T> and IEnumerator<T>.  We saw that when we create classes that implement IEnumerable<T>, we can use foreach and the LINQ extension methods.  We also saw how we can use the "yield return" statement to eliminate the need for a separate enumerator class.

But take another look at our IteratorSequence and FibonacciSequence when we *are* using the separate IEnumerator class:



Notice anything about these two classes?  They are exactly the same with the exception of what specific enumerator class they "new" up in the GetEnumerator() method.  This strikes me as a great place for us to add an abstraction.  Using the Strategy Pattern, we can create a generic Sequence class to which we can pass a specific enumerator class.  Next time, we'll take a look at the Strategy Pattern and how to implement it with these classes.

Happy Coding!

Tuesday, May 22, 2012

Next, Please! - A Closer Look at IEnumerable (Part 2 - Extension Methods and LINQ)

This is a continuation of "Next, Please! - A Closer Look at IEnumerable".  The articles in the series are collected together here: JeremyBytes - Downloads.

Last time we took a look at the Iterator Pattern and how IEnumerable<T> lets us use the "foreach" loop.  IEnumerable<T> also gives us access to a huge number of extension methods that make up LINQ (Language INtegrated Query).

Extension Methods
Extension methods allow us to add methods to a class -- with no subtyping required.  This means that we can even add methods to sealed classes, and the classes will behave as if our methods are native to the class.  (Technically, we are not adding methods to the class, but the usage appears that way.)  To explore extension methods a little further, we'll take a look a quick sample.  The source code is available here: Quick Byte: Extension Methods.

In this sample, we will add an extension method to IEnumerable<T>.  Here's the definition of our method:


The idea behind this method is that we take a collection (any collection that implements IEnumerable<T>), pass in a delimiter (such as a comma or pipe), and the method will output a string with all of the elements delimited with the specified value.

On its face, this method should be pretty easy to figure out.  First, it is a public static method (ToDelimitedString<T>()) that is part of a public static class (JBExtensions).  The only strange part of this method is that there is the "this" keyword before the first parameter (IEnumerable<T> input).  We'll come back to this in just a bit.

We can use this method just like we would use any other static method:


This is a button click event in a simple WPF application.  First, we create a variable called "months" which is a list of strings.  The Months.GetMonths() method will populate this list with the 12 calendar months.  Next, we populate a text box based on our static method.  Notice that we call this with the static class (JBExtensions), then the static method (ToDelimitedString<string>).  There are 2 parameters: our list (months) and the delimiter (a comma and a space).  This results in the following output:


But remember how we described extension methods: the ability to add a method to a class (or at least appear to do so).  Because we used the "this" keyword before the first parameter, we can treat the method as if it were a method on that first parameter.  In our example, this means that it would behave as if the "ToDelimitedString" method is part of the "months" class.  Here's what that looks like:


Now instead of calling "JBExtensions.ToDelimitedString...", we call "months.ToDelimitedString...".  The parameters of the method are then any remaining parameters (after the first one).  In this case, we have the delimiter parameter.  If we compare the syntax to what we had before, this version is much more readable.  It is clear what is happening: we are operating on the "months" object by calling "ToDelimitedString" with a delimiter as the parameter.  The great thing about Visual Studio is that we get full IntelliSense as well.  When we type "months." we will see "ToDelimitedString" in the list of methods that are available (assuming that all of the requirements for an extension method are met).

Here are the requirements:
  • Extension methods must be public static methods in a public static class.  The class name itself is unimportant.
  • Extension methods are declared by including the "this" keyword in front of the first parameter.  The "this" keyword can only be used with the first parameter.
  • Extension methods are used by including the namespace of the public static class in the scope where the methods are to be used.  This means that extension methods can be collected in a shared library that is used across projects, if desired.
That's all there is to it.

IEnumerable<T> and LINQ
So, why all of this talk about extension methods?  Well, it turns out that much of Language INtegrated Query (LINQ) is implemented as extension methods on IEnumerable<T>.  This gives us a ton of really cool functionality that we can use with our collections.  The one qualification is that we need to include a using statement for "System.Linq" in order for the extension methods to be available (the 3rd bullet point, above).  The good news is that Visual Studio includes System.Linq as part of the default "using" statements for most code-file types.

LINQ offers us multiple syntaxes for implementation.  The first is using Query Syntax.  This syntax looks a lot like a SQL query (except the "select" is at the end instead of the beginning).  Here's a sample:


The "people" variable is the same one we saw last time.  It is a list of Person that is populated by the static "GetPeople" method (just a list of hard-coded values).  If you are familiar with SQL queries, then the second statement should look pretty familiar.  We are looking in the "people" object, doing a filter based on the FirstName property, and sorting the records based on the StartDate property.

If we take a look at the members of the IEnumerable<T> interface, we will see all of the Extension Methods: IEnumerable<T> Interface.  And when I say that there is a ton of functionality, this includes over 50 unique extension methods -- and several of those extension methods have multiple overloads.

By using these methods directly, we can implement LINQ by using what is often called Fluent Syntax.  Here's what the same query looks like using the fluent syntax:


The "Where" extension method takes an IEnumerable<T> and returns an IEnumerable<T>.  This means that we can keep concatenating the extension methods, so we end up with people.Where().OrderBy().  As you can imagine, this could make our code lines quite long.  Fortunately, C# allows us to add line breaks before the dots:


You can see that this is a bit more legible.  One thing to point out about LINQ extension methods is that they generally take lambda expressions in the parameters.  For a full discussion of Lambda Expressions and LINQ, please refer to Learn to Love Lambdas.

When trying to decide between Query Syntax and Fluent Syntax, there are a few things to note.  First, not all of the extension methods have Query Syntax keywords.  The basics are there (from, where, orderby, join, groupby, select), but others are not (such as First(), Single(), Count(), Average()).  This means that there are times when you may need to mix the Query Syntax and Fluent Syntax.  And that's okay.  Ultimately, which syntax you use is up to you.  Personally, if you are comfortable with lambda expressions, I think that the Fluent Syntax is easier to read and work with.  But that's just my preference.

Look at the IEnumerable<T> Extension Methods
Look at the extension methods that LINQ provides.  No, really.  Look at the Extension Methods.  There are a ton of useful methods in there.  They aren't all just "query" type methods (where, order by, grouping, etc.).  They also include aggregations such as average and count, and scalar types such as min, max, first, and last.  So, look through the list.

Here's a sample of how the extension methods can make your code much more concise.  This sample is taken from Introduction to Data Templates and Value Converters in Silverlight (this works in WPF and Windows Phone as well).  Here is the output:


The Person class includes a Rating field, which is an integer value from 0 to 10.  For the UI above, we want to take the value of the "Rating (Stars)" text box and count the number of asterisks that it contains.  We want to ignore any character that is not an asterisk.  Here is the "traditional" way of doing this (this is located in the "RatingStarConverter" in the "Converters.cs" file):


This takes the incoming value (from the text box), and assigns it to the "input" variable.  Then it uses a foreach loop to iterate through the characters of that "string" (remember from last time that string implements IEnumerable<char>, so we can use it with foreach).  If the current character is an asterisk, then we increment our rating value.

But the IEnumerable<T> extension methods give us a much quicker way of writing this: Count().


This code does exactly the same thing as the foreach loop.  The Count() method takes an optional predicate parameter that lets us set a condition on the items that we want to count.  In this case, we only count the characters that are asterisks.

There are tons of other useful methods.  Some of my favorites are Average, Count, Skip, SingleOrDefault, OrderBy, Except (the opposite of Where), and Sum.  Pretty much all of these methods use Func<> of some type in the declaration.  Wherever you see "Func<>", treat it as a big sign that says, "PUT YOUR LAMBDA EXPRESSION HERE."  Of course, the more comfortable you are with delegates and lambda expressions, the better off you'll be.  You can refer to Learn to Love Lambdas and Get Func<>-y: Delegates in .NET for additional information and samples.

The extension methods on the IEnumerable<T> interface make this an extremely powerful interface.  By simply including the System.Linq namespace, we get over 50 additional functions that can make our code more concise and readable.

Next Time
Today, we took a look what extension methods are and how we can use them to add functionality to existing classes.  Then we saw how LINQ adds a huge number of extension methods to the IEnumerable<T> interface.  These extension methods let us harness the power of LINQ in any of our collections (or other classes that implement IEnumerable<T>).

Next time, we'll create our own class that implements the IEnumerable<T> interface.  This will give us a chance to explore the interface in a bit more detail and to see exactly what we need to do in order to create our own enumerable classes.

Happy Coding!