Pages

Monday, July 4, 2011

Using C# Yield for Readability and Performance

I must have read about "yield" a dozen times. Only recently have I began to understand what it does, and the real power that comes along with it. I’m going to show you some examples of where it can make your code more readable, and potentially more efficient.

To give you a very quick overview of how the yield functionality works, I first want to show you an example without it. The following code is simple, yet it’s a common pattern in the latest project I’m working on.

1.  IList<string> FindBobs(IEnumerable<string> names)  

2.  {  

3.      var bobs = new List<string>();  

4.    

5.      foreach(var currName in names)  

6.      {  

7.          if(currName == "Bob")  

8.              bobs.Add(currName);  

9.      }  

10.   

11.     return bobs;  

12. }  

Notice that I take in an IEnumerable<string>, and return an IList<string>. My general rule of thumb has been to be as lenient as possible with my input, and as strict as possible with my output. For the input, it clearly makes sense to use IEnumerable if you’re just going to be looping through it with a foreach. For the output, I try to use an interface so that the implementation can be changed. However, I chose to return the list because the caller may be able to take advantage of the fact that I already went through the work of making it a list.

The problem is, my design isn’t chainable, and it’s creating lists all over the place. In reality, this probably doesn’t add up to much, but it’s there nonetheless.

Now, let’s take a look at the "yield" way of doing it, and then I’ll explain how and why it works:

1.  IEnumerable<string> FindBobs(IEnumerable<string> names)  

2.  {  

3.      foreach(var currName in names)  

4.      {  

5.          if(currName == "Bob")  

6.              yield return currName;  

7.      }  

8.  }  

In this version, we have changed the return type to IEnumerable<string>, and we’re using "yield return". Notice that I’m no longer creating a list. What’s happening is a little confusing, but I promise it’s actually incredibly simple once you understand it.

When you use the "yield return" keyphrase, .NET is wiring up a whole bunch of plumbing code for you, but for now you can pretend it’s magic. When you start to loop in the calling code (not listed here), this function actually gets called over and over again, but each time it resumes execution where it left off.

Typical Implementation

Yield Implementation

  1. Caller calls function
  2. Function executes and returns list
  3. Caller uses list
  1. Caller calls function
  2. Caller requests item
  3. Next item returned
  4. Goto step #2

Although the execution of the yield implementation is a little more complicated, what we end up with is an implementation that "pulls" items one at a time instead of having to build an entire list before returning to the client.

In regards to the syntax, I personally think the yield syntax is simpler, and does a better job conveying what the method is actually doing. Even the fact that I’m returning IEnumerable tells the caller that its only concern should be that it can "foreach" over the return data. The caller can now make their own decisionif they want to put it in a list, possibly at the expense of performance.

In the simple example I provided, you might not see much of an advantage. However, you’ll avoid unnecessary work when the caller can "short-circuit" or cancel looping through all of the items that the function will provide. When you start chaining methods using this technique together, this becomes more likely, and the amount of work saved can possibly multiply.

One of my first reservations with using yield was that there is a potential performance implication. Since c# is keeping track of what is going on in what is essentially a state machine, there is a bit of overhead. Unfortunately, I can’t find any information that demonstrates the performance impact. I do think that the potential advantages I mentioned should outweigh the overhead concerns.

Conclusion

Yield can make your code more efficient and more readable. It’s been around since .NET 2.0, so there’s not much reason to avoid understanding and using it.

Have you been using yield in interesting ways? Have you ever been bitten by using it? Leave a comment and let me know!

 

Monday, March 7, 2011

Difference between List, ObservableCollection and INotifyPropertyChanged

Introduction
This article describes the basic understanding between List, ObservableCollection and INotifyPropertyChanged.
Difference between List<T>, ObservableCollection<T> and INotifyPropertyChanged
List<T>
It represents a strongly typed list of objects that can be accessed by index. It provides methods to search, sort, and manipulate lists. The List<T> class is the generic equivalent of the ArrayList class. It implements the IList<T> generic interface using an array whose size is dynamically increased as required.
http://www.codeproject.com/KB/silverlight/SLListVsOCollections/List.JPG
Drawbacks
In ASP.NET, we simply use DataSource and DataBind() to bind the data, but in Silverlight it is slightly different. Databinding in ASP.NET is done in a stateless way - once that binding operation is completed, it's a done deal and if you want to change anything, you have to manipulate the underlying controls that were created as a result of the data binding, or else change the underlying data objects and call DataBind() again. That’s what we are used to – but it’s not a good practice.
listgrid.JPG
In the sample application, the values in the list are added, removed and changed during runtime in the code behind. The changes in the list will not be updated to the UI (Datagrid).
ObservableCollection<T>
ObservableCollection is a generic dynamic data collection that provides notifications (using an interface "INotifyCollectionChanged") when items get added, removed, or when the whole collection is refreshed.
Note: WCF service proxy class in Silverlight will use this type of collection by default.
observablecollection.JPG
Drawbacks
It does not provide any notifications when any property in the collection is changed.
observablecollectiongrid.JPG
In the sample application, the values in the observable collection are added, removed and changed during runtime in the code behind. The operations (adding and removing an item) in the observable collection will be updated to the UI (Datagrid). But any change in the existing item will not be updated to the UI.
INotifyPropertyChanged
INotifyPropertyChanged is not a collection, it’s an interface used in the data object classes to provide PropertyChanged notification to clients when any property value gets changed. This will allow you to raise PropertyChanged event whenever the state of the object changes (Added, Removed, and Modified) to the point where you want to notify the underlying collection or container that the state has changed.
inotifypropertychanged.JPG
inotifypropertychangedgrid.JPG
INotifyPropertyChanged is compatible on all type of collections like List<T>, ObservableCollection<T>, etc. The code snippet which uses INotifyPropertyChanged is shown below:
public class UserNPC:INotifyPropertyChanged
{
    private string name;
    public string Name {
        get { return name; }
        set { name = value; onPropertyChanged(this, "Name"); }
    }
    public int grade;
    public int Grade {
        get { return grade; }
        set { grade = value; onPropertyChanged(this, "Grade"); }
    }

    // Declare the PropertyChanged event
    public event PropertyChangedEventHandler PropertyChanged;

    // OnPropertyChanged will raise the PropertyChanged event passing the
    // source property that is being updated.
    private void onPropertyChanged(object sender, string propertyName)
    {
        if (this.PropertyChanged != null)
        {
            PropertyChanged(sender, new PropertyChangedEventArgs(propertyName));
        }
    }
}
In the above code snippet, whenever a value is set to a property, the method “onPropertyChanged” will be called which in turn raises the PropertyChanged event.