Archive | July, 2009

C# Actions part 2: Lazy evaluation

14 Jul

Lazy Evaluation example:

In a previous post I talked about C# Actions and how they are a useful feature that could provide new shorthand for lazy evaluation. I have since found an excellent article [1] which demonstrates lazy evaluation with LINQ. The advantages in that article show how LINQ queries can minimize memory usage by evaluating upon enumeration rather than just allocating memory for everything the query would return.

Func

Actions are delegates that have a void return type. This makes sense if you are using Actions as event handlers, but for other use cases you will want a return type. In these cases you will want to use Func. One issue I have seen with Func is when you want don’t know how many parameters your function is going to take. If the number is variable then you must implement up to the amount of parameters you want (if overloading). I noticed a few examples of that in the Ninject 1.x source code. To generalize Func and Actions you can use the ‘Delegate’ type (note: the captialization).

A real world use case

A reason for lazy evaluation could be that you want to perform a group of service calls at one time. The service calls could be a transaction style interaction which would want to be disposed afterwards and some of the service calls could be surplus to requirement. If I had a user interface which required a list of products to be loaded, then that screen may not need that data reloaded if it is moving from a screen which has that data loaded. That service call could be pre-evaluated (ie lazy evaluation) to check to see if it is necessary.

Observable Dictionary

13 Jul

As a fan of ObservableCollections, I have created an observable dictionary. I have provided the code below. I have implemented interfaces that should allow for WPF databinding. The reason I needed such a class is because I needed an event to indicate when the dictionary was updated. I kept this class small (it is just a wrapper over a dictionary).

public class ObservableDictionary<TKey, TValue> :

        IDictionary<TKey, TValue>,

        INotifyCollectionChanged,

        INotifyPropertyChanged

{

    public event NotifyCollectionChangedEventHandler CollectionChanged;

    public event PropertyChangedEventHandler PropertyChanged;

 

    readonly IDictionary<TKey, TValue> _dictionary = new Dictionary<TKey, TValue>();

 

    public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()

    {

        return _dictionary.GetEnumerator();

    }

 

    IEnumerator IEnumerable.GetEnumerator()

    {

        return GetEnumerator();

    }

 

    public void Add(KeyValuePair<TKey, TValue> item)

    {

        _dictionary.Add(item);

 

        if (CollectionChanged != null)

            CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add));

 

        if (PropertyChanged != null)

        {

            PropertyChanged(this, new PropertyChangedEventArgs("Keys"));

            PropertyChanged(this, new PropertyChangedEventArgs("Values"));

        }

    }

 

    public void Clear()

    {

        int keysCount = _dictionary.Keys.Count;

 

        _dictionary.Clear();

 

        if (keysCount == 0) return; //dont trigger changed event if there was no change.

 

        if (CollectionChanged != null)

            CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));

 

        if (PropertyChanged != null)

        {

            PropertyChanged(this, new PropertyChangedEventArgs("Keys"));

            PropertyChanged(this, new PropertyChangedEventArgs("Values"));

        }

    }

 

    public bool Contains(KeyValuePair<TKey, TValue> item)

    {

        return _dictionary.Contains(item);

    }

 

    public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)

    {

        _dictionary.CopyTo(array, arrayIndex);

    }

 

    public bool Remove(KeyValuePair<TKey, TValue> item)

    {

        bool remove = _dictionary.Remove(item);

 

        if (!remove) return false; //don’t trigger change events if there was no change.

 

        if (CollectionChanged != null)

            CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove));

 

        if (PropertyChanged != null)

        {

            PropertyChanged(this, new PropertyChangedEventArgs("Keys"));

            PropertyChanged(this, new PropertyChangedEventArgs("Values"));

        }

 

        return true;

    }

 

    public int Count

    {

        get { return _dictionary.Count; }

    }

 

    public bool IsReadOnly

    {

        get { return _dictionary.IsReadOnly; }

    }

 

    public bool ContainsKey(TKey key)

    {

        return _dictionary.ContainsKey(key);

    }

 

    public void Add(TKey key, TValue value)

    {

        _dictionary.Add(key, value);

 

        if (CollectionChanged != null)

            CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add));

 

        if (PropertyChanged != null)

        {

            PropertyChanged(this, new PropertyChangedEventArgs("Keys"));

            PropertyChanged(this, new PropertyChangedEventArgs("Values"));

        }

    }

 

    public bool Remove(TKey key)

    {

        bool remove = _dictionary.Remove(key);

 

        if (!remove) return false;

 

        if (CollectionChanged != null)

            CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove));

 

        if (PropertyChanged != null)

        {

            PropertyChanged(this, new PropertyChangedEventArgs("Keys"));

            PropertyChanged(this, new PropertyChangedEventArgs("Values"));

        }

 

        return true;

    }

 

    public bool TryGetValue(TKey key, out TValue value)

    {

        return _dictionary.TryGetValue(key, out value);

    }

 

    public TValue this[TKey key]

    {

        get { return _dictionary[key]; }

        set

        {

            bool changed = _dictionary[key].Equals(value);

 

            if (!changed) return; //if there are no changes then we don’t need to update the value or trigger changed events.

 

            _dictionary[key] = value;

 

            if (CollectionChanged != null)

                CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace));

 

            if (PropertyChanged != null)

            {

                PropertyChanged(this, new PropertyChangedEventArgs("Keys"));

                PropertyChanged(this, new PropertyChangedEventArgs("Values"));

            }

        }

    }

 

    public ICollection<TKey> Keys

    {

        get { return _dictionary.Keys; }

    }

 

    public ICollection<TValue> Values

    {

        get { return _dictionary.Values; }

    }

}

 

A link to another (Larger) implementation of an Observable Dictionary: http://www.drwpf.com/Blog/Default.aspx?tabid=36&EntryID=8

CC0
To the extent possible under law, Richard Wilburn has waived all copyright and related or neighboring rights to Observable Dictionary. This work is published from New Zealand.

C# Action’s

5 Jul

When playing around with UI events it is sometimes handy to use lambda notations of actions to do a tidy inline event-action handler definition such as:

Button1.Click += (sender, args) => Debug.WriteLine("Button Click");
 

If we delve a little deeper into Actions, we can use them to pass around code snippets/functions.

Action<String> action = (input) => Debug.WriteLine("Testing" + input); 
 

I have heard many arguments against functional features such as actions in C# however I do feel that they are very useful in edge cases. One such case could be the mass adding of items to a dictionary, such as:

var namesDictionary = new Dictionary<int, string>();
 
namesDictionary.Add(1,"One");
namesDictionary.Add(2,"Two");
namesDictionary.Add(3,"Three");
 

If we wanted to keep our code maintainable we might want to reduce our dependency to the Add method (especially if we had lots of dictionary add statements).

Action<int,string> addAction = (key,value) => namesDictionary.Add(key,value);
//Action<int,string> addAction = namesDictionary.Add; //short syntax

addAction(1, "One");  //etc
 

Note that this dictionary example is a bad example as the collection initialization could be used here which is likely the most optimal solution. The following shows how the collection initialization could have been used:

var namesDictionary = new Dictionary<int, string> {{1, "One"}, {2, "Two"}, {3, "Three"}};
 

This example also could have been solved more optimally using extension method(s), by extending the dictionary, dependency injection, lambda foreach statement, foreach loop etc. With that said, Actions are important in allowing for lazy evaluation/delayed invocation. I am not going to get into lazy evaluation in this post, but I recommend checking out the Haskell language community for lazy evaluation ideas. I highly recommend the following link for understanding how evaluation/manipulation of lambda expressions work.

http://msdn.microsoft.com/en-us/library/bb397951.aspx