Some well known .NET interfaces (IEnumerable, IClonable and IComparable)

This post is based on chapter 9 of Andrew Troelsen’s “Pro C# 2008 and the .Net Platform” available from Apress.

Any type that implements IEnumerable can be used by the foreach statement.
You have two choices if you want to implement IEnumerable – either maintain a member of type ArrayList (or similar) that already implements IEnumerable, and expose this, or you can roll your own.

To roll your own, you need a method called GetEnumerator() which returns an object of the IEnumerator type – so just to be clear: the IEnumerable interface stipulates that you must return an object of type IEnumerator, from a method called GetEnumerator().
You can start handcrafting this, but really what you do is use the “yield return” keyword. So for instance you might have an array (which does not support IEnumerable) – and you can simply place a for loop inside the GetEnumerator() and yield each object out.
What yield does is it stores the current locaton, and restarts execution from this point next time the method is called – which is exactly what an iterator is.

IClonable objects are able to return an identical copy of themselves via the Clone() method. Note that best practise is to return a deep copy of the object (i.e. a new object with the exact same state) as opposed to a shallow copy (a copy of the reference, pointing to the same object on the heap).
Note that the object type has a method MemberwiseClone that can be used for this eaxact purpose – note that if yuu have a type containing only value types you can use this for a deep copy – however if your type has any reference types, you must create a new object to obtain a proper deep copied clone.

IComparable objects are indeed comparable. Wonders never cease. This is most often used in things like Array.Sort(array) calls. To implement this, you need to supply a CompareTo(object obj) method, which should return an int.
Less than zero indicates your object is before the object passed in,  Zero means it’s equal and larger than zero it’s after.
So you can do what you like here, compare strings, Ids, dates – whatever makes sense for your object, just return a signed integer value. However do note that all the types I just mentioned (strings, ints and dates) all implement IComparable so make sure you simply pass the call through where possible (i.e. don’t start writing convuluted if/else staments to compare to ints).

Note that you can build custom comparers (say if you wanted more than one way to compare a given object) by creating a class that implements the IComparer interface. You must then supply a method that has a Compare(obj a, obj b) method. So you could perhaps have two of these for say a Product class – on to compare SKU and one to compare the name.
A neat (and recommended) way of doing this, is to create these IComparer implementations, and then expose them through the Product class. So you get something like this:

		public class Product
		{
			//Use C# 2008 auto-implemented properties:
			public int SKU { get; set; }
			public string Name { get; set; }

			public static IComparer SortBySKU
			{
				get { return (IComparer)new ProductSKUComparer(); }
			}

			public static IComparer SortByName
			{
				get { return (IComparer)new ProductNameComparer(); }
			}
		}

		public class ProductSKUComparer : IComparer
		{
			public int Compare(object x, object y)
			{
				return ((Product)x).SKU.CompareTo(((Product)y).SKU);
			}
		}

		public class ProductNameComparer : IComparer
		{
			public int Compare(object x, object y)
			{
				return ((Product)x).Name.CompareTo(((Product)y).Name);
			}
		}

		public class TestIt
		{
			public TestIt()
			{
				Product[] products = { new Product(), new Product(), new Product() };
				//Assume we have names and SKU on these products:
				Array.Sort(products, Product.SortBySKU);
				//Or:
				Array.Sort(products, Product.SortByName);
			}
		}
Advertisements

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: