Showing posts with label extension method. Show all posts
Showing posts with label extension method. Show all posts

Thursday, February 24, 2011

Example of C# lazy, functional programming: SplitUp()

I seem to be on a bit of roll here regarding extension methods. They are by no means a silver bullet, but this method is a nice LINQ-like lazy method on a generic sequence that is a perfect fit. I think it nicely illustrates how you can write your own such functional methods that are usable like LINQ methods that are part of the .NET framework, and have some of the same characteristics.

This SplitUp() extension method takes a sequence and splits it up into subsequences that each have a maximum length. For instance, you can split a sequence (list, collection, array, etc.) of 64 integers into an enumerable sequence of List<int> instances of lengths 10, 10, 10, 10, 10, 10 and 4 by calling SplitUp(10) on it.

Here is the source:

namespace peSHIr.Utilities
{
 using System;
 using System.Linq;
 using System.Text;
 using System.Collections.Generic;

 /// <summary>Utility code for working with sequences</summary>
 public static class SequenceUtility
 {
  /// <summary>Split up sequence of items</summary>
  /// <typeparam name="T">Item type</typeparam>
  /// <param name="input">Input sequence</param>
  /// <param name="n">Maximum number of items per sublists</param>
  /// <returns>Sequence of lists with a maximum
  /// of <paramref name="n"/> items</returns>
  /// <remarks>Might need a suppression of code analysis rule
  /// CA1006 because of the nested generic type in the method
  /// signature.</remarks>
  public static IEnumerable<IEnumerable<T>>
   SplitUp<T>(this IEnumerable<T> input, int n)
  {
   // Non-lazy error checking
   if (input == null) throw new ArgumentNullException("input");
   if (n < 1) throw new ArgumentOutOfRangeException("n", n, "<1");
   return SplitUpLazy(input, n);
  }

  private static IEnumerable<IEnumerable<T>>
   SplitUpLazy<T>(IEnumerable<T> input, int n)
  {
   // Lazy yield based implementation
   var list = new List<T>();
   foreach (T item in input)
   {
    list.Add(item);
    if (list.Count == n)
    {
     yield return list;
     list = new List<T>();
    }
   }
   if (list.Count > 0) yield return list;
   yield break;
  }
 }
}

As you can see, the SplitUp function behaves like built in LINQ functions because its implementation is split up (pun intented...). The public variant basically just does argument checking, so you get the ArgumentExceptions on improper use immediately when calling the method, while the private actual implementation uses yield statements to implement the actual splitting of the input sequence into lists of at most n elements.

This mirrors the implementation of LINQ methods, as shown in the very informative Edulinq blog series on their implementation by Jon Skeet, the so called superuser of stackoverflow.com.

I hope you find this extra illustration of this technique informative, or at least find the method itself useful. Personally I have used it for splitting up sequences of input records from a file into batches for processing by a web service that had a maximum request size. I would love to hear what you have used it for, so all comments are welcome.

(Added later: For those of you that like to have working pieces of example code to play with for code nuggets like this, please check out my next blog post.)

Wednesday, February 23, 2011

Safely set NumericUpDown control value

Very quick post about an extension method on the NumericUpDown control I once put to great use. It's small, quick, simple, needs the System.Windows.Forms and System namespaces, but can be of great use. Enjoy:

public static void SafeValue(this NumericUpDown c, decimal value)
{
   c.Value = Math.Max(c.Minimum, Math.Min(value, c.Maximum));
}

The principle will no doubt work on similar controls for WPF/Silverlight or other controls - like sliders - that at least have a value that is constrained by properties and might give exceptions if you try to set the value to an illegal value.

Tuesday, November 30, 2010

Some handy extension methods for argument checking

After a quick Twitter interaction with Marc Jacobi I thought I'd post a small set of extension methods I like to use for argument checking:
using System;
using System.Collections.Generic;
using System.Text;

namespace peSHIr.Utilities
{
    public static class Guards
    {
        public static void GuardNull
            (this object argument, string argumentName)
        {
            if (argument == null)
            {
                throw new ArgumentNullException(
                          argumentName,
                          "No object supplied");
            }
        }

        public static void GuardNull
            (this string argument, string argumentName)
        {
            if (String.IsNullOrEmpty(argument))
            {
                throw new ArgumentNullException(
                          argumentName,
                          "No text supplied (or text is empty)");
            }
        }

        public static void GuardZero
            (this int argument, string argumentName)
        {
            if (argument == 0)
            {
                throw new ArgumentNullException(
                          argumentName,
                          "The number zero is not allowed here");
            }
        }

        public static void GuardNull<T>
            (this Nullable<T> argument, string argumentName)
            where T:struct
        {
            if (argument.HasValue == false)
            {
                throw new ArgumentNullException(
                          argumentName,
                          "Empty nullable type not allowed here");
            }
        }

        public static void GuardMinimum<T>
            (this T argument, T lower, string argumentName)
            where T : IComparable<T>
        {
            if (argument.CompareTo(lower) < 0)
            {
                throw new ArgumentOutOfRangeException(
                          argumentName, argument,
                          string.Format("Minimum allowed: {0}", lower));
            }
        }

        public static void GuardMaximum<T>
            (this T argument, T upper, string argumentName)
            where T : IComparable<T>
        {
            if (argument.CompareTo(upper) > 0)
            {
                throw new ArgumentOutOfRangeException(
                          argumentName, argument,
                          string.Format("Maximum allowed: {0}", upper));
            }
        }

        public static void GuardRange<T>
            (this T argument, T lower, T upper, string argumentName)
            where T : IComparable<T>
        {
            if (argument.CompareTo(lower) < 0 || argument.CompareTo(upper) > 0)
            {
                throw new ArgumentOutOfRangeException(
                          argumentName, argument,
                          string.Format("Allowed: [{0},{1}]", lower, upper));
            }
        }
    }
}
When you can use code contracts this is probably preferable. Otherwise, these little extension methods can come in really handy for some general cases.

Monday, October 19, 2009

Efficient checking whether IEnumerable contains data

Have you ever needed to check - in a LINQ context, or otherwise - whether an IEnumerable<T> (or plain IEnumerable) contained any elements?

Of course a check using the Count<T>() extension method to check for an element count of zero works here, but this would be... unfortunate... for sequences yielding large numbers of elements because of the O(n) linear behavior.

Maybe the following source code (or the LINQ Any() method, see comments) could be of use to you in those cases from now on:

/// <summary>Sequence contains at least 1 item?</summary>
/// <typeparam name="T">Type of elements</typeparam>
/// <param name="sequence">Sequence to check</param>
/// <returns>true/false</returns>
public static bool NotEmpty<T>(this IEnumerable<T> sequence)
{
  return sequence.GetEnumerator().MoveNext();
}

/// <summary>Sequence contains at least 1 item?</summary>
/// <param name="sequence">Sequence to check</param>
/// <returns>true/false</returns>
public static bool NotEmpty(this IEnumerable sequence)
{
  return sequence.GetEnumerator().MoveNext();
}

These extension methods check whether the given sequence contains elements or not, but does so taking only O(1) constant time. In other words: the entire sequence is not fully evaluated, but the minimal work is being done to check if the sequence contains at least one element.