static void

.Net Collections


The collection/list interfaces

The functional interfaces


Implement IList and/or IDictionary. For dictionaries (name/values):

Implementing interfaces

Custom Collections

Thread Safe

You can get a synchronised wrapper around a Stack: Stack mySyncdStack = Stack.Synchronized( myStack ) but for derived classes lock(myCollection.SyncRoot)

Lists with Delegates

Very useful functional programming.

delegate(DatedItem d) {
return (d.Id == key);
List.Sort(Comparison<T>) items.Sort(
delegate(DatedItem p1, DatedItem p2) {
return p1.Name.CompareTo(p2.Name);
List.ConvertAll<TOut>(Comparison<T, TOut>) items.ConvertAll<Object>(
delegate(DatedItem p1) {
return (Object)p1;


See SortableBindingList<T> (for Windows.Forms)

Copying to an array to sort with a delegate (here, sorting ListItems in asp DropDownList)

private void SortListControl(ListControl ddl)
    ListItemCollection c = ddl.Items;
    ListItem[] items = new ListItem[c.Count];
    c.CopyTo(items, 0);
    Array.Sort(items, delegate(ListItem a, ListItem b)
                              return a.Text.CompareTo(b.Text);

Sorting with nullable properties has a slighly more involved delegate

private void SortList()
    //DeatedObject.Date is a nullable date
    List<DatedObject> olist = new List<DatedObject>();
    olist.Add(new DatedObject(DateTime.Now.AddDays(1)));
    olist.Add(new DatedObject(DateTime.Now));
    olist.Add(new DatedObject()); //null date
    olist.Sort(CompareDatedObjects); //IList does not have a Sort
    comboBox1.DataSource = olist;
    comboBox1.DisplayMember = "Date";
private static int CompareDatedObjects(DatedObject x, DatedObject y)
    if (x.Date == null)
        return (y.Date == null) ? 0 : -1; //If x is null and y is not null, y is greater.
    else // If x is not null...
        if (y.Date == null)
            return 1; // y is null so x is greater.
            return x.Date.Value.CompareTo(y.Date); // both non-null, compare the properties

Nongeneric to generic ILists

When using an older style library in .net 2

/// <summary>
/// Converts nongeneric list to generic list.
/// Just a generic way of doing foreach (string s in untypedList) genericList.Add(s);
/// </summary>
/// <typeparam name="T">The type.
/// If any in the list aren't the type, throws an exception</typeparam>
/// <param name="list">The untyped list.</param>
/// <returns>A generic list</returns>
/// <example><code>IList&lt;string&gt; typedList = ConvertToGenericList&lt;string&gt;(untypedList);
/// </code></example>
/// <exception cref="InvalidCastException"/>
private static List<T> ConvertToGenericList<T>(ICollection list)
    //copy it into a concrete ArrayList
    ArrayList untypedList = new ArrayList(list);
    //then create the generic list from the arrayList's ToArray
    //with funky typeof/as [] casting
    return new List<T>(untypedList.ToArray(typeof (T)) as T[]);


//simple join
var simpleJoin = from category in categories
            //joins use "equals" not "=="
            join product in products on category.Id equals product.CategoryId
            orderby category.Id
            select new { category.CategoryName, product.ProductName };
//group join (hierarchical outer join)
var groupJoin = from category in categories
             join product in products on category.Id equals product.Id
                    into productsForCategory
             select new { category.Id, Products = productsForCategory };
//groupby - products by category
var groups = from product in products
             group product by product.CategoryId;


//find duplicates
var dupes = from category in categories
            group category by category.Id
            into categoryGroup
            where categoryGroup.Count() > 1
            select categoryGroup.Key;
var noDupes = categories.Distinct(); //if you have IEqualityComparer
//or without a comparer
var noDupes2 = from category in categories
               //join to a distinct list of ids
               join id in categories.Select(x => x.Id).Distinct()
                    on category.Id equals id
               select category;
var noDupes3 = from category in categories
               //group them and just get the first
               group category by category.Id into categoryGroup
               select categoryGroup.First();

Set operations

var inBoth = list1.Intersect(list2);
Log("In both", inBoth);
var inList1Only = list1.Except(list2);
Log("Only in list 1", inList1Only);
var union = list1.Union(list2); //compare list1.Concat(list2)
Log("Both lists merged", union);
//.net 4 merge
var zip = list1.Zip(list2, (a, b) => a + " " + b);
Log("Zipped together", zip);
bool isInSameOrder = list1.SequenceEqual(list2);