Jacob Carpenter’s Weblog

November 24, 2007

Another set of extension methods

Filed under: csharp, extension methods, Ruby — Jacob @ 3:16 pm

In addition to the interesting diversions we’ve taken, I do want to continue presenting potentially useful code samples too. So here’s a fresh set of ruby inspired extensions:

public static IEnumerable<IndexValuePair<T>> WithIndex<T>(this IEnumerable<T> source)
{
    int position = 0;
    foreach (T value in source)
        yield return new IndexValuePair<T>(position++, value);
}    

public static void Each<T>(this IEnumerable<T> source, Action<T> action)
{
    foreach (T item in source)
        action(item);
}

public static void EachWithIndex<T>(this IEnumerable<T> source, Action<T, int> action)
{
    Each(WithIndex(source), pair => action(pair.Value, pair.Index));
}

I’ll include the mundane definition of IndexValuePair<T> (along with parameter validation) at the end of this post. But spend some time looking at these very simple methods.

diagram 1

Notice how once we’ve defined WithIndex and Each, we can combine them to define EachWithIndex. When we chain Each to the result of WithIndex, the type of the Action must be converted accordingly:

diagram 2

This is easily accomplished by the statement:

pair => action(pair.Value, pair.Index)

So with the added definition of IndexValuePair<T> and parameter validation, we add to our collection extensions the following:

using System;
using System.Collections.Generic;

public static class CollectionEx
{
    public static void Each<T>(this IEnumerable<T> source, Action<T> action)
    {
        if (source == null)
            throw new ArgumentNullException("source");
        if (action == null)
            throw new ArgumentNullException("action");

        foreach (T item in source)
            action(item);
    }

    public static void EachWithIndex<T>(this IEnumerable<T> source, Action<T, int> action)
    {
        if (source == null)
            throw new ArgumentNullException("source");
        if (action == null)
            throw new ArgumentNullException("action");

        Each(WithIndexIterator(source), pair => action(pair.Value, pair.Index));
    }

    public static IEnumerable<IndexValuePair<T>> WithIndex<T>(this IEnumerable<T> source)
    {
        if (source == null)
            throw new ArgumentNullException("source");

        return WithIndexIterator(source);
    }

    private static IEnumerable<IndexValuePair<T>> WithIndexIterator<T>(IEnumerable<T> source)
    {
        int position = 0;
        foreach (T value in source)
            yield return new IndexValuePair<T>(position++, value);
    }
}

public struct IndexValuePair<T>
{
    public IndexValuePair(int index, T value)
    {
        m_index = index;
        m_value = value;
    }

    public int Index
    {
        get { return m_index; }
    }
    public T Value
    {
        get { return m_value; }
    }

    readonly int m_index;
    readonly T m_value;
}
Advertisements

November 19, 2007

Named parameters { Part = 2 }

Filed under: csharp — Jacob @ 7:19 am

Note: the following is presented merely as an interesting diversion. It’s not a technique I’m legitimately proposing to the C# community, though I certainly welcome any feedback you may have.

Continuing our discussion from last time, we’re going to look at what we can do with object initialization syntax to enable immutable type initialization. But first we’re going to need a contrived example immutable type:

public class CoffeeOrder 
{ 
    public string DrinkName 
    { 
        get { return m_drinkName; } 
    } 
    public bool AddSugar 
    { 
        get { return m_addSugar; } 
    } 
    public bool IncludeRoom 
    { 
        get { return m_includeRoom; } 
    } 
    public bool IsDecaf 
    { 
        get { return m_isDecaf; } 
    } 
    public int SizeOunces 
    { 
        get { return m_sizeOunces; } 
    } 

    readonly string m_drinkName; 
    readonly bool m_addSugar; 
    readonly bool m_includeRoom; 
    readonly bool m_isDecaf; 
    readonly int m_sizeOunces; 
}

This is obviously not a post on type design.

So we want to be able create instances of these using initialization-like syntax. We also don’t want to define a number of constructors to accommodate all of the combinations of optional parameters.

The simplest way we can achieve these goals would be to create a CoffeeOrder constructor that took an object. Then, using reflection, we could examine the properties of any passed-in value to see what fields we should set.

public CoffeeOrder() { } 

public CoffeeOrder(object initializer) 
{ 
    /* reflect over "initializer" and set fields */ 
}

We could then create CoffeOrders like so:

CoffeeOrder order = new CoffeeOrder(new 
{ 
    DrinkName = "Drip", 
    SizeOunces = 16, 
});

Unfortunately, that wouldn’t be very reusable. Every time we defined a new immutable type, we’d need to rewrite the reflection code. We also aren’t being very clear to the caller what the passed in object is supposed to be.

Let’s create an abstraction for the initializer parameter:

public class NamedArgs 
{ 
    public static NamedArgs Create(object initializer) 
    { 
        return new NamedArgs { m_data = initializer, m_datatype = initializer.GetType() }; 
    } 

    object m_data; 
    Type m_datatype; 
}

Our CoffeeOrder constructor signature becomes:

public CoffeeOrder(NamedArgs args)

And the calling code is:

CoffeeOrder order = new CoffeeOrder(NamedArgs.Create(new 
{ 
    DrinkName = "Drip", 
    SizeOunces = 16, 
}));

We’ve improved the CoffeeOrder constructor signature a bit. It’s certainly more descriptive of what is expected. The code to call the constructor is incrementally less beautiful now, though.

But let’s move on and see about actually getting data out of this NamedArgs object.

We’re going to use reflection APIs (System.Reflection) to do so, though we’re only going to scratch the surface of what’s possible. Right now, we’re just going to look up property values by string names. We’ll look at a more interesting way to refer to the properties before we’re done.

public class NamedArgs 
{ 
    // ... 

    public void SetFromArg<TValue>(string argumentName, ref TValue result) 
    { 
        // get the PropertyInfo for the requested argument (if available) 
        PropertyInfo infoProp = m_datatype.GetProperty(argumentName); 
        if (infoProp != null) 
        { 
            // set the result 
            result = (TValue) infoProp.GetValue(m_data, null); 
        } 
    } 
}

Rather than returning default(TValue) when the argument isn’t specified, or creating a TryGetValue sort of API, we’re only going to set the referenced value if the NamedArgs instance contains an argument matching the name. That way, the class that calls this method can set up default values before calling our method and not worry about explicitly handling any unspecified, optional arguments. So let’s update the anemic CoffeeOrder constructor:

public CoffeeOrder(NamedArgs args) 
{ 
    args.SetFromArg("DrinkName", ref m_drinkName); 
    args.SetFromArg("AddSugar", ref m_addSugar); 
    args.SetFromArg("IncludeRoom", ref m_includeRoom); 
    args.SetFromArg("IsDecaf", ref m_isDecaf); 
    args.SetFromArg("SizerOunces", ref m_sizeOunces); 
}

That’s surprisingly unoffensive. I mean, sure, there are a lot of magic strings, but it’s not the worst thing I’ve ever seen.

On the other hand, it does kind of suck. We can improve it, though, using the power of expression trees.

Property accesses are a type of expression (MemberExpression to be specific). We can pass in a lambda that performs property access on an argument and we can treat that expression as data to figure out the name of the member that’s being accessed.

So in the case of our CoffeeOrder constructor calling SetFromArg, we want an expression of type Expression<Func<CoffeeOrder, T>> where T is the target property’s value type. But CoffeeOrder will be the type parameter for all of the expressions, and we don’t want to lose our type inference on the ref parameter (if we specify one type argument to SetFromArg, we have to specify them all). So let’s create a new derivation of NamedArgs to hold that fixed type argument:

public class NamedArgs 
{ 
    /* ... */ 

    public static NamedArgs<T> For<T>(object initializer) 
    { 
        return new NamedArgs<T> { m_data = initializer, m_datatype = initializer.GetType() }; 
    } 
}

public class NamedArgs<T> : NamedArgs 
{ 
    public void SetFromArg<TValue>(Expression<Func<T, TValue>> propertyAccessor, ref TValue result) 
    { 
        // examine the expression tree for member access 
        MemberExpression accessor = propertyAccessor.Body as MemberExpression; 
        if (accessor == null) 
            throw new ArgumentException("Invalid expression type. Expecting member access.", "propertyAccessor"); 

        // set the value from the specified argument name 
        SetFromArg(accessor.Member.Name, ref result); 
    } 
}

We added the For method to the non-generic NamedArgs class just for aesthetics. NamedArgs.For<CoffeeOrder>(/*...*/) looks better than NamedArgs<CoffeeOrder>.For(/*...*/).

Now our CoffeeOrder constructor looks like:

public CoffeeOrder(NamedArgs<CoffeeOrder> args) 
{ 
    args.SetFromArg(c => c.DrinkName, ref m_drinkName); 
    args.SetFromArg(c => c.AddSugar, ref m_addSugar); 
    args.SetFromArg(c => c.IncludeRoom, ref m_includeRoom); 
    args.SetFromArg(c => c.IsDecaf, ref m_isDecaf); 
    args.SetFromArg(c => c.SizeOunces, ref m_sizeOunces); 
}

Which is nice because now we’re even more explicit about what the CoffeeOrder constructor is expecting. And, when we’re writing the calls to SetFromArg, we get intellisense for the available properties.

Our calling code becomes:

CoffeeOrder order = new CoffeeOrder(NamedArgs.For<CoffeeOrder>(new 
{ 
    DrinkName = "Drip", 
    SizeOunces = 16, 
}));

Which is certainly on the verbose side, but not abhorrent.

Closing

We’ve created a type that encapsulates the notion of named parameters with the intent of using it to construct immutable types. We’ve tailored some behaviors specifically to that intended usage, but it’s not closed from use by other methods.

Since anonymous types are immutable, they are thread-safe. The NamedArgs class with its fields that reference immutable type instances is thread-safe as well (though callers will obviously have to protect any values passed as ref parameters).

There are certainly features we could add. One commonly requested feature for immutable types is the ability to initialize one instance from another instance with only a few overridden values. Something like:

public static NamedArgs<T> From<T>(T baseValue, object overrides)

There are also certainly drawbacks to our technique. Some would argue the use of reflection alone is a drawback.

More discerning folks will point out that it’s terribly easy to give incorrectly named arguments. It’s nice that we got intellisense support while implementing the constructor by using expression trees, but we don’t have any such niceties when we’re creating a NamedArgs instance used for calling that constructor.

A more robust solution could certainly validate the property names for generic NamedArgs instances, but that would involve extra reflection.

I hope this post has been enjoyable and inspires other creative solutions. I’d love to hear any feedback you have on this.

Full example source follows:

using System; 
using System.Linq.Expressions; 
using System.Reflection; 

class Program 
{ 
    static void Main(string[] args) 
    { 
        var order1 = new CoffeeOrder(NamedArgs.For<CoffeeOrder>(new 
        { 
            DrinkName = "Drip", 
            SizeOunces = 16, 
        })); 

        var order2 = new CoffeeOrder(NamedArgs.For<CoffeeOrder>(new 
        { 
            DrinkName = "Drip", 
            SizeOunces = 12, 
            IsDecaf = true, 
            AddSugar = true, 
        })); 

        Console.WriteLine(order1); 
        Console.WriteLine(order2); 

        if (System.Diagnostics.Debugger.IsAttached) 
        { 
            Console.Write("Press any key to continue . . . "); 
            Console.ReadKey(true); 
        } 
    } 
} 

public class NamedArgs 
{ 
    public static NamedArgs Create(object initializer) 
    { 
        return new NamedArgs { m_data = initializer, m_datatype = initializer.GetType() }; 
    } 

    public static NamedArgs<T> For<T>(object initializer) 
    { 
        return new NamedArgs<T> { m_data = initializer, m_datatype = initializer.GetType() }; 
    } 

    public void SetFromArg<TValue>(string argumentName, ref TValue result) 
    { 
        // get the PropertyInfo for the requested argument (if available) 
        PropertyInfo infoProp = m_datatype.GetProperty(argumentName); 
        if (infoProp != null) 
        { 
            // set the result 
            result = (TValue) infoProp.GetValue(m_data, null); 
        } 
    } 

    object m_data; 
    Type m_datatype; 
} 

public class NamedArgs<T> : NamedArgs 
{ 
    public void SetFromArg<TValue>(Expression<Func<T, TValue>> propertyAccessor, ref TValue result) 
    { 
        // examine the expression tree for member access 
        MemberExpression accessor = propertyAccessor.Body as MemberExpression; 
        if (accessor == null) 
            throw new ArgumentException("Invalid expression type. Expecting member access.", 
                "propertyAccessor"); 

        // set the value from the specified argument name 
        SetFromArg(accessor.Member.Name, ref result); 
    } 
} 

public class CoffeeOrder 
{ 
    public CoffeeOrder() { } 

    public CoffeeOrder(NamedArgs<CoffeeOrder> args) 
    { 
        args.SetFromArg(c => c.DrinkName, ref m_drinkName); 
        args.SetFromArg(c => c.AddSugar, ref m_addSugar); 
        args.SetFromArg(c => c.IncludeRoom, ref m_includeRoom); 
        args.SetFromArg(c => c.IsDecaf, ref m_isDecaf); 
        args.SetFromArg(c => c.SizeOunces, ref m_sizeOunces); 
    } 

    public string DrinkName 
    { 
        get { return m_drinkName; } 
    } 

    public bool AddSugar 
    { 
        get { return m_addSugar; } 
    } 

    public bool IncludeRoom 
    { 
        get { return m_includeRoom; } 
    } 

    public bool IsDecaf 
    { 
        get { return m_isDecaf; } 
    } 

    public int SizeOunces 
    { 
        get { return m_sizeOunces; } 
    } 

    public override string ToString() 
    { 
        return String.Format("Coffee Order: {0} oz. {1}\n   IsDecaf     = {2}\n" + 
            "   IncludeRoom = {3}\n   AddSugar    = {4}", SizeOunces, DrinkName, 
            IsDecaf, IncludeRoom, AddSugar); 
    } 

    readonly string m_drinkName; 
    readonly bool m_addSugar; 
    readonly bool m_includeRoom; 
    readonly bool m_isDecaf; 
    readonly int m_sizeOunces; 
}

November 17, 2007

Named parameters and immutable type initialization

Filed under: csharp — Jacob @ 3:53 pm

Eric Lippert and Joe Duffy have each started blogging about immutable types (here and here, respectively). I’m a big fan of immutable types as the simplest solution to many thread-safety issues. And regardless of the number of threads your application utilizes, value types should always be immutable (and you should read the Framework Design Guidelines).

But there is a bit of a problem: C# 3.0 introduced "object initialization syntax."

Object initialization

Hopefully you’re familiar with the feature already, but here’s an example:

var settings = new XmlReaderSettings { CloseInput = true, IgnoreWhitespace = true };

XmlReaderSettings only has a default, parameterless constructor. The designers of the type expect you to individually set a number of properties on an instance before handing it off to XmlReader.Create. C# 3.0 now lets you initialize the instance in one statement.

Well, okay: you get to write one statement, but when compiled, that single statement turns back into a multi-step process of creating the instance and then setting the specified properties/fields individually. But it sure makes for nicer looking source.

Unfortunately, this compiler magic also means you cannot use object initialization syntax with immutable types. Since immutable types, by definition, don’t expose property setters, object initialization can’t compile.

Strangely enough, anonymous type instances (for which object initialization was created) are immutable. This post covers some of the changes to support the immutablity of anonymous types, including: "Anonymous type construction will no longer be realized as an Object initalizer (since the anonymous type is created in a single call), but as a single constructor call."

It’s a shame object initialization wasn’t changed to support immutablity, rather than anonymous types being modified to not use object initialization.

Named parameters

Object initialization isn’t unlike the concept of named parameters. In C# (with one caveat), all method/constructor parameters are positional parameters. That means that, while you give your method parameters descriptive names in your method declaration, the caller only cares about matching the order of their arguments to your method signature. Your method’s parameter names have no bearing on the caller.

With named parameters, parameters are allowed to be specified in any order and can even be optional. They can also make the source code more descriptive. Going back to our XmlReaderSettings example, imagine the constructor took a number of boolean parameters:

public XmlReaderSettings(bool closeInput, bool ignoreWhitespace /*, etc. */) { /*...*/ }

Our calling code would look like:

var settings = new XmlReaderSettings(true, true);

That’s obviously silly.

With named parameters, creation would look just like our object initialization example with parentheses instead of curly braces. There wouldn’t be any ambiguity about which properties were being set.

In some languages that don’t support named parameters (such as Ruby), people have used dictionaries to pass name/value pairs to methods. With C#’s collection initialization, a similar technique could be used. But .NET’s strong type system doesn’t support dictionaries with mixed value types very nicely. You could use a Dictionary<string, object>, but then value types would have to be boxed and there’d be casting to get values out… it’d be a mess.

Immutable type initialization

Hopefully, the future of C# includes stronger support for immutable types (including initialization scenarios). But until then, we can have some fun abusing anonymous types to meet our immutable type initialization needs. We’ll look at how in the next post.

November 16, 2007

Unnecessary MoveNext: do we care?

Filed under: csharp — Jacob @ 4:59 pm

In the last post we looked at some counts for MoveNext, when iterating IEnumerables returned by Take/Skip. Now we’re going to attempt to answer the question: do we care?

Let’s step back a little bit and strip this code down to the bare essentials:

using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static IEnumerable<int> NumbersOneToTen()
    {
        yield return 1;
        yield return 2;
        yield return 3;
        yield return 4;
        yield return 5;
        yield return 6;
        yield return 7;
        yield return 8;
        yield return 9;
        yield return 10;
    }

    static void Main()
    {
        using (IEnumerator<int> enumerator = NumbersOneToTen()
            .GetEnumerator())
        {
            enumerator.MoveNext();
        }
    }
}

Here, we have a console application that merely calls MoveNext on the Enumerator returned by NumbersOneToTen. We’re explicitly controlling the enumeration to avoid any ambiguity introduced by using foreach. For instance, we’ve ensured that the Current property of the enumerator is never accessed.

I’ve set a breakpoint on the line containing MoveNext with the intent to hit F11 (Step Into). [It probably bears mentioning that I’m using Visual Studio 2008 Beta 2.]

When you run that (F5), you’ll see that pressing F11 once steps into the NumbersOneToTen method, pressing it a second time moves to the line with the first yield return, and pressing it a third time returns control back to our Main method (with the enumerator positioned on the first item).

The only potentially surprising thing here is that calling NumbersOneToTen() doesn’t actually step into the method, but that’s the beauty of deferred evaluation.

So, what are some things we could do with the sequence that would make calling MoveNext more interesting?

One interesting thing we can do is project elements from the sequence as different elements. In .NET 2.0, this operation was called ConvertAll. In .NET 3.5, we use the Select extension method.

Let’s modify our Main method a bit:

using (var enumerator = NumbersOneToTen().Select(n => "Number " + n)
    .GetEnumerator())

Here, we’re projecting all of the numbers from 1..10 to the strings: “Number 1″..”Number 10”. Now let’s step through our code again: F11 once steps into NumbersOneToTen; F11 moves to the line with the first yield return; F11 steps into the lambda passed to Select.

I’m not just emphasizing that line because it’s a miraculous feat of the debugger that it can step into embedded statements.

I’m emphasizing that statement because we haven’t accessed Current at all. We’ve only asked to advance the enumerator. Every time we call MoveNext, it appears our projection is evaluated. I was actually surprised by that fact.

So, given the example from the last post, if we were to naively introduce our simple projection:

foreach (var batch in NumbersOneToTen().Select(n => "Number " + n).Slice(3))
    foreach (var item in batch)
        Console.WriteLine(item);

We would end up doing 50 unnecessary string concatenations. It’s also not hard to conceive of a projection more expensive than string concatenation.

But we can improve that, right? Certainly the same result is achieved if we project the items after splitting them into batches:

foreach (var batch in NumbersOneToTen().Slice(3))
    foreach (var item in batch.Select(n => "Number " + n))
        Console.WriteLine(item);

There! Now we’re no longer unnecessarily projecting elements when splitting into batches; we only execute the projection as we consume the batch’s items.

But projection isn’t the only operation we can perform on sequences. Filtering is pretty useful, too. In .NET 2.0, we used FindAll; in 3.5, we use Where:

var evens = NumbersOneToTen().Where(n => n % 2 == 0);

Here, we’re filtering the sequence of numbers from 1..10 to a sequence containing only the even numbers.

Unfortunately, this is also an example of a case where we can’t move the sequence operation into the item-consuming loop. If we filter the outer sequence (prior to slicing), we get two slices: { 2, 4, 6}, { 8, 10 }. However, if we filter at the item-consuming level, we get four slices, none of which are the desired size (3): { 2 }, { 4, 6 }, { 8 }, { 10 }.

So, given a Take/Skip-based implementation of Slice with a filtered sequence, we’re stuck with 50 unnecessary predicate evaluations.

That’s enough to convince me that Take/Skip should be avoided in this context, despite the elegance of the proposed implementation.

Slice revisited

Filed under: csharp — Jacob @ 10:43 am

So Dustin responded to my last post in the comments of his original post with the following code snippet:

public static bool IsEmpty<T>(this IEnumerable<T> sequence)
{
    if (sequence == null)
        throw new ArgumentNullException("sequence");

    if (sequence.GetEnumerator().MoveNext())
        return false;

    return true;
}

public static IEnumerable<IEnumerable<T>> Slice<T>(this IEnumerable<T> sequence, int size)
{
    if (sequence == null)
        throw new ArgumentNullException("sequence");
    if (size <= 0)
        throw new ArgumentOutOfRangeException("size");

    while (!sequence.IsEmpty())
    {
        yield return sequence.Take(size);
        sequence = sequence.Skip(size);
    }
}

First of all: wow. That is remarkably succinct and elegant code capturing what we’re expressing with slice. (The parameter validation won’t occur until enumeration begins, but that’s easy to change.)

The trouble is that Take and Skip hide a lot of potentially expensive, unnecessary enumeration.

To look at it, we can create an iterator method to represent our source sequence:

public static IEnumerable<int> NumbersOneToTen()
{
    yield return 1;
    yield return 2;
    yield return 3;
    yield return 4;
    yield return 5;
    yield return 6;
    yield return 7;
    yield return 8;
    yield return 9;
    yield return 10;
}

Now, rather than calling slice with an array, we can set a breakpoint in this method and actually step through the calls to MoveNext(). [Note: this is a little unfair because some methods that accept an IEnumerable actually internally optimize for situations where they have, say, an ICollection/IList (for example, Reverse). This does not appear to be the case with Take/Skip, though.]

Here are the tallies for MoveNext() when executing the following code:

foreach (var slice in NumbersOneToTen().Slice(3))
    foreach (var item in slice)
        Console.WriteLine(item);
  MoveNexts Total
IsEmpty [false] 1 1
First slice [1, 2, 3] 3 4
IsEmpty [false] 4 8
Second slice [4, 5, 6] 6 14
IsEmpty [false] 7 21
Third slice [7, 8, 9] 9 30
IsEmpty [false] 10 40
Fourth slice [10] 11 51
IsEmpty [true] 11 62

It’s of some note that all of the slices, except the last, require n calls to MoveNext where n is the last element of the slice. Returning the last slice (as well as checking IsEmpty at the end) requires n+1 MoveNexts, because Take asks for more elements than there are remaining in the sequence. The 11th MoveNext simply returns false.

Now, I certainly don’t think Take or Skip are inherently evil. There are certainly contexts in which their use is completely benign.

But, the question emerges: do we care about 62 calls to MoveNext when 11 will do? Comments?

Ruby inspired extension method

Filed under: csharp, extension methods, Ruby — Jacob @ 12:00 am

Reading Dustin Campbell‘s latest post reminded me that I really like Ruby’s Enumerable mixin.

One of the compelling methods in that type is each_slice (and the related enum_slice). The each/enum distinction to a C# developer can be understood as the distinction between a void method that takes a delegate, and an iterator method (a method that uses yield return) that returns an IEnumerable.

With the advent of C# 3.0 and the built-in Enumerable extension methods, returning an IEnumerable is a pretty powerful construct—developers aren’t limited to just foreach-ing over the results anymore.

So here’s a C# Slice extension method that is roughly the equivalent of Ruby’s enum_slice method:

using System;
using System.Collections.Generic;

namespace RubyInspiredExtensions
{
    public static class CollectionEx
    {
        /// <summary>
        /// Iterates the specified sequence returning arrays of each slice of <paramref name="size"/> elements.
        /// The last array may contain fewer that <paramref name="size"/> elements.
        /// </summary>
        /// <typeparam name="T">The sequence element type.</typeparam>
        /// <param name="sequence">The source sequence.</param>
        /// <param name="size">The desired slice size.</param>
        /// <returns>A sequence of arrays containing the elements from the specified sequence.</returns>
        public static IEnumerable<T[]> Slice<T>(this IEnumerable<T> sequence, int size)
        {
            // validate arguments
            if (sequence == null)
                throw new ArgumentNullException("sequence");
            if (size <= 0)
                throw new ArgumentOutOfRangeException("size");

            // return lazily evaluated iterator
            return SliceIterator(sequence, size);
        }

        // SliceIterator: iterator implementation of Slice
        private static IEnumerable<T[]> SliceIterator<T>(IEnumerable<T> sequence, int size)
        {
            // prepare the result array
            int position = 0;
            T[] resultArr = new T[size];

            foreach (T item in sequence)
            {
                // NOTE: performing the following test at the beginning of the loop ensures that we do not needlessly
                // create empty result arrays for sequences with even numbers of elements [(sequence.Count() % size) == 0]
                if (position == size)
                {
                    // full result array; return to caller
                    yield return resultArr;

                    // create a new result array and reset position
                    resultArr = new T[size];
                    position = 0;
                }

                // store the current element in the result array
                resultArr[position++] = item;
            }

            // no elements in source sequence
            if (position == 0)
                yield break;

            // resize partial final slice
            if (position < size)
                Array.Resize(ref resultArr, position);

            // return final slice
            yield return resultArr;
        }
    }
}

Create a free website or blog at WordPress.com.