What is the best or most interesting use of Extension Methods you've seen?

Viewed 11710

I'm starting to really love extension methods... I was wondering if anyone her has stumbled upon one that really blew their mind, or just found clever.

An example I wrote today:

Edited due to other users' comments:

public static IEnumerable<int> To(this int fromNumber, int toNumber) {
    while (fromNumber < toNumber) {
        yield return fromNumber;
        fromNumber++;
    }
}

This allows a for loop to be written as a foreach loop:

foreach (int x in 0.To(16)) {
    Console.WriteLine(Math.Pow(2, x).ToString());
}

I can't wait to see other examples! Enjoy!

40 Answers

This is one that's been getting some play from me lately:

public static IDisposable Tag(this HtmlHelper html, string tagName)
{
    if (html == null)
        throw new ArgumentNullException("html");

    Action<string> a = tag => html.Write(String.Format(tag, tagName));
    a("<{0}>");
    return new Memento(() => a("</{0}>"));
}

Used like:

using (Html.Tag("ul"))
{
    this.Model.ForEach(item => using(Html.Tag("li")) Html.Write(item));
    using(Html.Tag("li")) Html.Write("new");
}

Memento is a handy class:

public sealed class Memento : IDisposable
{
    private bool Disposed { get; set; }
    private Action Action { get; set; }

    public Memento(Action action)
    {
        if (action == null)
            throw new ArgumentNullException("action");

        Action = action;
    }

    void IDisposable.Dispose()
    {
        if (Disposed)
            throw new ObjectDisposedException("Memento");

        Disposed = true;
        Action();
    }
}

And to complete the dependencies:

public static void Write(this HtmlHelper html, string content)
{
    if (html == null)
        throw new ArgumentNullException("html");

    html.ViewContext.HttpContext.Response.Write(content);
}

The full solution is too large to put here, but I wrote a series of extension methods that would allow you to easily convert a DataTable into a CSV.

public static String ToCSV(this DataTable dataTable)
{
    return dataTable.ToCSV(null, COMMA, true);
}  

public static String ToCSV(this DataTable dataTable, String qualifier)
{
    return dataTable.ToCSV(qualifier, COMMA, true);
}

private static String ToCSV(this DataTable dataTable, String qualifier, String delimiter, Boolean includeColumnNames)
{
    if (dataTable == null) return null;

    if (qualifier == delimiter)
    {
        throw new InvalidOperationException(
            "The qualifier and the delimiter are identical. This will cause the CSV to have collisions that might result in data being parsed incorrectly by another program.");
    }

    var sbCSV = new StringBuilder();

    var delimiterToUse = delimiter ?? COMMA;

    if (includeColumnNames) 
        sbCSV.AppendLine(dataTable.Columns.GetHeaderLine(qualifier, delimiterToUse));

    foreach (DataRow row in dataTable.Rows)
    {
        sbCSV.AppendLine(row.ToCSVLine(qualifier, delimiterToUse));
    }

    return sbCSV.Length > 0 ? sbCSV.ToString() : null;
}

private static String ToCSVLine(this DataRow dataRow, String qualifier, String delimiter)
{
    var colCount = dataRow.Table.Columns.Count;
    var rowValues = new String[colCount];

    for (var i = 0; i < colCount; i++)
    {
        rowValues[i] = dataRow[i].Qualify(qualifier);
    }

    return String.Join(delimiter, rowValues);
}

private static String GetHeaderLine(this DataColumnCollection columns, String qualifier, String delimiter)
{
    var colCount = columns.Count;
    var colNames = new String[colCount];

    for (var i = 0; i < colCount; i++)
    {
        colNames[i] = columns[i].ColumnName.Qualify(qualifier);
    }

    return String.Join(delimiter, colNames);
}

private static String Qualify(this Object target, String qualifier)
{
    return qualifier + target + qualifier;
}

At the end of the day, you could call it like this:

someDataTable.ToCSV(); //Plain old CSV
someDataTable.ToCSV("\""); //Double quote qualifier
someDataTable.ToCSV("\"", "\t"); //Tab delimited

I'm not a fan of the INotifyPropertyChanged interface requiring that property names are passed as strings. I want a strongly-typed way to check at compile time that I'm only raising and handling property changes for properties that exist. I use this code to do that:

public static class INotifyPropertyChangedExtensions
{
    public static string ToPropertyName<T>(this Expression<Func<T>> @this)
    {
        var @return = string.Empty;
        if (@this != null)
        {
            var memberExpression = @this.Body as MemberExpression;
            if (memberExpression != null)
            {
                @return = memberExpression.Member.Name;
            }
        }
        return @return;
    }
}

In classes that implement INotifyPropertyChanged I include this helper method:

protected void NotifySetProperty<T>(ref T field, T value,
    Expression<Func<T>> propertyExpression)
{
    if (field == null ? value != null : !field.Equals(value))
    {
        field = value;
        this.NotifyPropertyChanged(propertyExpression.ToPropertyName());
    }
}

So that finally I can do this kind of thing:

private string _name;
public string Name
{
    get { return _name; }
    set { this.NotifySetProperty(ref _name, value, () => this.Name); }
}

It's strongly-typed and I only raise events for properties that actually change their value.

Well this isn't exactly clever but I've modified the ----OrDefault methods so you could specify a default item inline instead of checking for null later in your code:

    public static T SingleOrDefault<T> ( this IEnumerable<T> source, 
                                    Func<T, bool> action, T theDefault )
    {
        T item = source.SingleOrDefault<T>(action);

        if (item != null)
            return item;

        return theDefault;
    }

Its incredible simple but really helps clean up those null checks. Best used when your UI is expecting a list of X items, like a tournament system, or game player slots and you want to display "empty seats".

Usage:

    return jediList.SingleOrDefault( 
                 j => j.LightsaberColor == "Orange", 
               new Jedi() { LightsaberColor = "Orange", Name = "DarthNobody");

Two that I like to use are the InsertWhere<T> and RemoveWhere<T> Extension Methods that I've written. Working with ObservableCollections in WPF and Silverlight I often need to modify ordered lists without recreating them. These methods allow me to insert and remove according to a supplied Func, so .OrderBy() doesn't need to be re-called.

    /// <summary>
    /// Removes all items from the provided <paramref name="list"/> that match the<paramref name="predicate"/> expression.
    /// </summary>
    /// <typeparam name="T">The class type of the list items.</typeparam>
    /// <param name="list">The list to remove items from.</param>
    /// <param name="predicate">The predicate expression to test against.</param>
    public static void RemoveWhere<T>(this IList<T> list, Func<T, bool> predicate)
    {
        T[] copy = new T[] { };
        Array.Resize(ref copy, list.Count);
        list.CopyTo(copy, 0);

        for (int i = copy.Length - 1; i >= 0; i--)
        {
            if (predicate(copy[i]))
            {
                list.RemoveAt(i);
            }
        }
    }

    /// <summary>
    /// Inserts an Item into a list at the first place that the <paramref name="predicate"/> expression fails.  If it is true in all cases, then the item is appended to the end of the list.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="list"></param>
    /// <param name="obj"></param>
    /// <param name="predicate">The sepcified function that determines when the <paramref name="obj"/> should be added. </param>
    public static void InsertWhere<T>(this IList<T> list, T obj, Func<T, bool> predicate)
    {
        for (int i = 0; i < list.Count; i++)
        { 
            // When the function first fails it inserts the obj paramiter. 
            // For example, in a list myList of ordered Int32's {1,2,3,4,5,10,12}
            // Calling myList.InsertWhere( 8, x => 8 > x) inserts 8 once the list item becomes greater then or equal to it.
            if(!predicate(list[i]))
            {
                list.Insert(i, obj);
                return;
            }
        }

        list.Add(obj);
    }

Edit:
Talljoe made some significant improvements to the RemoveWhere/RemoveAll, that I had hastily constructed. With ~3mill items removing every third one the new version takes only ~50 milliseconds (less then 10 if it can call List.RemoveAll !) as opposed to the RemoveWhere 's multiple seconds (I got tired of waiting for it.)

Here is his greatly improved version, thanks again!

    public static void RemoveAll<T>(this IList<T> instance, Predicate<T> predicate)
    {
        if (instance == null)
            throw new ArgumentNullException("instance");
        if (predicate == null)
            throw new ArgumentNullException("predicate");
        if (instance is T[])
            throw new NotSupportedException();

        var list = instance as List<T>;
        if (list != null)
        {
            list.RemoveAll(predicate);
            return;
        }

        int writeIndex = 0;
        for (int readIndex = 0; readIndex < instance.Count; readIndex++)
        {
            var item = instance[readIndex];
            if (predicate(item)) continue;

            if (readIndex != writeIndex)
            {
                instance[writeIndex] = item;
            }
            ++writeIndex;
        }

        if (writeIndex != instance.Count)
        {
            for (int deleteIndex = instance.Count - 1; deleteIndex >= writeIndex; --deleteIndex)
            {
                instance.RemoveAt(deleteIndex);
            }
        }
    }

Here's one I hacked together, so feel free to pick holes in it. It takes an (ordered) list of integers and returns a list of strings of contiguous ranges. eg:

1,2,3,7,10,11,12  -->  "1-3","7","10-12"

The function (within a static class):

public static IEnumerable<string> IntRanges(this IEnumerable<int> numbers)
{
    int rangeStart = 0;
    int previous = 0;

    if (!numbers.Any())
        yield break;

    rangeStart = previous = numbers.FirstOrDefault();

    foreach (int n in numbers.Skip(1))
    {
        if (n - previous > 1) // sequence break - yield a sequence
        {
            if (previous > rangeStart)
            {
                yield return string.Format("{0}-{1}", rangeStart, previous);
            }
            else
            {
                yield return rangeStart.ToString();
            }
            rangeStart = n;
        }
        previous = n;
    }

    if (previous > rangeStart)
    {
        yield return string.Format("{0}-{1}", rangeStart, previous);
    }
    else
    {
        yield return rangeStart.ToString();
    }
}

Usage example:

this.WeekDescription = string.Join(",", from.WeekPattern.WeekPatternToInts().IntRanges().ToArray());

This code is used to convert data from a DailyWTF-worthy timetabling application. WeekPattern is a bitmask stored in a string "0011011100...". WeekPatternToInts() converts that to an IEnumerable<int>, in this case [3,4,6,7,8], which becomes "3-4,6-8". It provides the user with a compact description of the academic week ranges that a lecture occurs on.

I have various .Debugify extension methods that are useful for dumping objects to a log file. For example, here's my Dictionary debugify (I have these for List, Datatable, param array, etc.):

public static string Debugify<TKey, TValue>(this Dictionary<TKey, TValue> dictionary) {
    string Result = "";

    if (dictionary.Count > 0) {
        StringBuilder ResultBuilder = new StringBuilder();

        int Counter = 0;
        foreach (KeyValuePair<TKey, TValue> Entry in dictionary) {
            Counter++;
            ResultBuilder.AppendFormat("{0}: {1}, ", Entry.Key, Entry.Value);
            if (Counter % 10 == 0) ResultBuilder.AppendLine();
        }
        Result = ResultBuilder.ToString();
    }
    return Result;
}

And here's one for a DbParameterCollection (useful for dumping database calls to the log file):

public static string Debugify(this DbParameterCollection parameters) {
    List<string> ParameterValuesList = new List<string>();

    foreach (DbParameter Parameter in parameters) {
        string ParameterName, ParameterValue;
        ParameterName = Parameter.ParameterName;

        if (Parameter.Direction == ParameterDirection.ReturnValue)
            continue;

        if (Parameter.Value == null || Parameter.Value.Equals(DBNull.Value))
            ParameterValue = "NULL";
        else
        {
            switch (Parameter.DbType)
            {
                case DbType.String:
                case DbType.Date:
                case DbType.DateTime:
                case DbType.Guid:
                case DbType.Xml:
                    ParameterValue
                        = "'" + Parameter
                                .Value
                                .ToString()
                                .Replace(Environment.NewLine, "")
                                .Left(80, "...") + "'"; // Left... is another nice one
                    break;

                default:
                    ParameterValue = Parameter.Value.ToString();
                    break;
            }

            if (Parameter.Direction != ParameterDirection.Input)
                ParameterValue += " " + Parameter.Direction.ToString();
        }

        ParameterValuesList.Add(string.Format("{0}={1}", ParameterName, ParameterValue));
    }

    return string.Join(", ", ParameterValuesList.ToArray());
}

Example result:

Log.DebugFormat("EXEC {0} {1}", procName, params.Debugify);
// EXEC spProcedure @intID=5, @nvName='Michael Haren', @intRefID=11 OUTPUT

Note that if you call this after your DB calls, you'll get the output parameters filled in, too. I call this on a line that includes the SP name so I can copy/paste the call into SSMS for debugging.


These make my log files pretty and easy to generate without interrupting my code.

A pair of extension methods to convert base-36 strings(!) to integers:

public static int ToBase10(this string base36)
{
    if (string.IsNullOrEmpty(base36))
        return 0;
    int value = 0;
    foreach (var c in base36.Trim())
    {
        value = value * 36 + c.ToBase10();
    }
    return value;
}

public static int ToBase10(this char c)
{
    if (c >= '0' && c <= '9')
        return c - '0';
    c = char.ToUpper(c);
    if (c >= 'A' && c <= 'Z')
        return c - 'A' + 10;
    return 0;
}

(Some genius decided that the best way to store numbers in the database was to encode them to strings. Decimals take too much space. Hex is better, but doesnt use the characters G-Z. So obviously you extend base-16 to base-36!)

I wrote a series of extension methods to make it easier to manipulate ADO.NET objects and methods :

Create a DbCommand from a DbConnection in one instruction :

    public static DbCommand CreateCommand(this DbConnection connection, string commandText)
    {
        DbCommand command = connection.CreateCommand();
        command.CommandText = commandText;
        return command;
    }

Add a parameter to a DbCommand :

    public static DbParameter AddParameter(this DbCommand command, string name, DbType dbType)
    {
        DbParameter p = AddParameter(command, name, dbType, 0, ParameterDirection.Input);
        return p;
    }

    public static DbParameter AddParameter(this DbCommand command, string name, DbType dbType, object value)
    {
        DbParameter p = AddParameter(command, name, dbType, 0, ParameterDirection.Input);
        p.Value = value;
        return p;
    }

    public static DbParameter AddParameter(this DbCommand command, string name, DbType dbType, int size)
    {
        return AddParameter(command, name, dbType, size, ParameterDirection.Input);
    }

    public static DbParameter AddParameter(this DbCommand command, string name, DbType dbType, int size, ParameterDirection direction)
    {
        DbParameter parameter = command.CreateParameter();
        parameter.ParameterName = name;
        parameter.DbType = dbType;
        parameter.Direction = direction;
        parameter.Size = size;
        command.Parameters.Add(parameter);
        return parameter;
    }

Access DbDataReader fields by name rather than index :

    public static DateTime GetDateTime(this DbDataReader reader, string name)
    {
        int i = reader.GetOrdinal(name);
        return reader.GetDateTime(i);
    }

    public static decimal GetDecimal(this DbDataReader reader, string name)
    {
        int i = reader.GetOrdinal(name);
        return reader.GetDecimal(i);
    }

    public static double GetDouble(this DbDataReader reader, string name)
    {
        int i = reader.GetOrdinal(name);
        return reader.GetDouble(i);
    }

    public static string GetString(this DbDataReader reader, string name)
    {
        int i = reader.GetOrdinal(name);
        return reader.GetString(i);
    }

    ...

Another (unrelated) extension method allows me to perform the DragMove operation (like in WPF) on WinForms forms and controls, see here.

Most examples for extension methods that I see here go against best practises. Extension methods are powerful, but should be used sparingly. In my experience, a static helper/utility class with old-school syntax would generally be preferrable for most of these.

There is something to say for extension methods for Enums, as it's not possible for them to have methods. If you define them in the same namespace as your Enum and in the same assembly, they work transparently.

While very simple, I find this one to be particularly useful since I get a page out of a full result set ten billion times a project:

public static class QueryableExtensions
{
    public static IQueryable<T> Page(this IQueryable<T> query, int pageNumber, int pageSize)
    {
        int skipCount = (pageNumber-1) * pageSize;
        query = query.Skip(skipCount);
        query = query.Take(pageSize);

        return query;
    }
}

To allow more functional combinator code:

    public static Func<T, R> TryCoalesce<T, R>(this Func<T, R> f, R coalesce)
    {
        return x =>
            {
                try
                {
                    return f(x);
                }
                catch
                {
                    return coalesce;
                }
            };
    }
    public static TResult TryCoalesce<T, TResult>(this Func<T, TResult> f, T p, TResult coalesce)
    {
        return f.TryCoalesce(coalesce)(p);
    }

Then I could write something like this:

    public static int ParseInt(this string str, int coalesce)
    {
        return TryCoalesce(int.Parse, str, coalesce);
    }

Another set I use quite often is for coalescing IDictionary methods:

    public static TValue Get<TKey, TValue>(this IDictionary<TKey, TValue> d, TKey key, Func<TValue> valueThunk)
    {
        TValue v = d.Get(key);
        if (v == null)
        {
            v = valueThunk();
            d.Add(key, v);
        }
        return v;
    }
    public static TValue Get<TKey, TValue>(this IDictionary<TKey, TValue> d, TKey key, TValue coalesce)
    {
        return Get(d, key, () => coalesce);
    }

And for working with collections in general:

    public static IEnumerable<T> AsCollection<T>(this T item)
    {
        yield return item;
    }

Then for tree-like structures:

    public static LinkedList<T> Up<T>(this T node, Func<T, T> parent)
    {
        var list = new LinkedList<T>();
        node.Up(parent, n => list.AddFirst(n));
        return list;
    }

So I can then easily traverse and operate upon a up a class like:

class Category
{
    public string Name { get; set; }
    public Category Parent { get; set; }
}

Next, to facilitate function composition and a more F# like way of programming in C#:

public static Func<T, T> Func<T>(this Func<T, T> f)
{
    return f;
}
public static Func<T1, R> Compose<T1, T2, R>(this Func<T1, T2> f, Func<T2, R> g)
{
    return x => g(f(x));
}

I like this one. It is a variation on the String.Split method that allows the use of an escape character to suppress splitting when the split character is intended to be in the actual string.

Extension method on int to decode a bitmask specifying days (with first day of week being Monday in this case) to an enumeration of DayOfWeek enums:

public static IEnumerable<DayOfWeek> Days(this int dayMask)
{
    if ((dayMask & 1) > 0) yield return DayOfWeek.Monday;
    if ((dayMask & 2) > 0) yield return DayOfWeek.Tuesday;
    if ((dayMask & 4) > 0) yield return DayOfWeek.Wednesday;
    if ((dayMask & 8) > 0) yield return DayOfWeek.Thursday;
    if ((dayMask & 16) > 0) yield return DayOfWeek.Friday;
    if ((dayMask & 32) > 0) yield return DayOfWeek.Saturday;
    if ((dayMask & 64) > 0) yield return DayOfWeek.Sunday;
}

This one creates array with single element added at the very beginning:

public static T[] Prepend<T>(this T[] array, T item)
{
    T[] result = new T[array.Length + 1];
    result[0] = item;
    Array.Copy(array, 0, result, 1, array.Length);
    return result;
}

string[] some = new string[] { "foo", "bar" };
...
some = some.Prepend("baz"); 

And this one helps me when I need to convert some expression to it's square:

public static double Sq(this double arg)
{
    return arg * arg;
}

(x - x0).Sq() + (y - y0).Sq() + (z - z0).Sq()

Here's another one I wrote:

    public static class StringExtensions
    {
        /// <summary>
        /// Returns a Subset string starting at the specified start index and ending and the specified end
        /// index.
        /// </summary>
        /// <param name="s">The string to retrieve the subset from.</param>
        /// <param name="startIndex">The specified start index for the subset.</param>
        /// <param name="endIndex">The specified end index for the subset.</param>
        /// <returns>A Subset string starting at the specified start index and ending and the specified end
        /// index.</returns>
        public static string Subsetstring(this string s, int startIndex, int endIndex)
        {
            if (startIndex < 0) throw new ArgumentOutOfRangeException("startIndex", "Must be positive.");
            if (endIndex < 0) throw new ArgumentOutOfRangeException("endIndex", "Must be positive.");
            if (startIndex > endIndex) throw new ArgumentOutOfRangeException("endIndex", "Must be >= startIndex.");
            return s.Substring(startIndex, (endIndex - startIndex));
        }

        /// <summary>
        /// Finds the specified Start Text and the End Text in this string instance, and returns a string
        /// containing all the text starting from startText, to the begining of endText. (endText is not
        /// included.)
        /// </summary>
        /// <param name="s">The string to retrieve the subset from.</param>
        /// <param name="startText">The Start Text to begin the Subset from.</param>
        /// <param name="endText">The End Text to where the Subset goes to.</param>
        /// <param name="ignoreCase">Whether or not to ignore case when comparing startText/endText to the string.</param>
        /// <returns>A string containing all the text starting from startText, to the begining of endText.</returns>
        public static string Subsetstring(this string s, string startText, string endText, bool ignoreCase)
        {
            if (string.IsNullOrEmpty(startText)) throw new ArgumentNullException("startText", "Must be filled.");
            if (string.IsNullOrEmpty(endText)) throw new ArgumentNullException("endText", "Must be filled.");
            string temp = s;
            if (ignoreCase)
            {
                temp = s.ToUpperInvariant();
                startText = startText.ToUpperInvariant();
                endText = endText.ToUpperInvariant();
            }
            int start = temp.IndexOf(startText);
            int end = temp.IndexOf(endText, start);
            return Subsetstring(s, start, end);
        }
    }

The motivation behind this one was simple. It always bugged me how the built in Substring method took startindex and length as it's parameters. It's ALWAYS much more helpful to do startindex and endindex. So, I rolled my own:

Usage:

        string s = "This is a tester for my cool extension method!!";
        s = s.Subsetstring("tester", "cool",true);

The reason I had to use Subsetstring was because Substring's overload already takes two ints. If anyone has a better name, please, let me know!!

cool, also loving Extensions!

here's a few.

This one will get the last Date of a Month:

<System.Runtime.CompilerServices.Extension()> _
    Public Function GetLastMonthDay(ByVal Source As DateTime) As DateTime
        Dim CurrentMonth As Integer = Source.Month
        Dim MonthCounter As Integer = Source.Month
        Dim LastDay As DateTime
        Dim DateCounter As DateTime = Source

        LastDay = Source

        Do While MonthCounter = CurrentMonth
            DateCounter = DateCounter.AddDays(1)
            MonthCounter = DateCounter.Month

            If MonthCounter = CurrentMonth Then
                LastDay = DateCounter
            End If
        Loop

        Return LastDay
    End Function

these two make reflection a bit easier:

 <System.Runtime.CompilerServices.Extension()> _
    Public Function GetPropertyValue(Of ValueType)(ByVal Source As Object, ByVal PropertyName As String) As ValueType
        Dim pInfo As System.Reflection.PropertyInfo

        pInfo = Source.GetType.GetProperty(PropertyName)

        If pInfo Is Nothing Then
            Throw New Exception("Property " & PropertyName & " does not exists for object of type " & Source.GetType.Name)
        Else
            Return pInfo.GetValue(Source, Nothing)
        End If
    End Function

    <System.Runtime.CompilerServices.Extension()> _
    Public Function GetPropertyType(ByVal Source As Object, ByVal PropertyName As String) As Type
        Dim pInfo As System.Reflection.PropertyInfo

        pInfo = Source.GetType.GetProperty(PropertyName)

        If pInfo Is Nothing Then
            Throw New Exception("Property " & PropertyName & " does not exists for object of type " & Source.GetType.Name)
        Else
            Return pInfo.PropertyType
        End If
    End Function

The extension methods I use the most would have to be the ones in the System.Linq.Enumerable class.

And a good and useful extension to that list you can find in MoreLinq.

few extensions I use mostly. first set is object extensions, really only for converting.

public static class ObjectExtension
{
    public static T As<T>(this object value)
    {
        return (value != null && value is T) ? (T)value : default(T);
    }

    public static int AsInt(this string value)
    {
        if (value.HasValue())
        {
            int result;

            var success = int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out result);

            if (success)
            {
                return result;
            }
        }

        return 0;
    }

    public static Guid AsGuid(this string value)
    {
        return value.HasValue() ? new Guid(value) : Guid.Empty;
    }
}

string extensions

public static class StringExtension
{
    public static bool HasValue(this string value)
    {
        return string.IsNullOrEmpty(value) == false;
    }

    public static string Slug(this string value)
    {
        if (value.HasValue())
        {
            var builder = new StringBuilder();
            var slug = value.Trim().ToLower();

            foreach (var c in slug)
            {
                switch (c)
                {
                    case ' ':
                        builder.Append("-");
                        break;
                    case '&':
                        builder.Append("and");
                        break;
                    default:

                        if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') && c != '-')
                        {
                            builder.Append(c);
                        }

                        break;
                }
            }

            return builder.ToString();
        }

        return string.Empty;
    }

    public static string Truncate(this string value, int limit)
    {
        return (value.Length > limit) ? string.Concat(value.Substring(0, Math.Min(value.Length, limit)), "...") : value;
    }
}

and last is some enum extensions

public static class EnumExtensions
{
    public static bool Has<T>(this Enum source, params T[] values)
    {
        var value = Convert.ToInt32(source, CultureInfo.InvariantCulture);

        foreach (var i in values)
        {
            var mask = Convert.ToInt32(i, CultureInfo.InvariantCulture);

            if ((value & mask) == 0)
            {
                return false;
            }
        }

        return true;
    }

    public static bool Has<T>(this Enum source, T values)
    {
        var value = Convert.ToInt32(source, CultureInfo.InvariantCulture);
        var mask = Convert.ToInt32(values, CultureInfo.InvariantCulture);

        return (value & mask) != 0;
    }

    public static T Add<T>(this Enum source, T v)
    {
        var value = Convert.ToInt32(source, CultureInfo.InvariantCulture);
        var mask = Convert.ToInt32(v, CultureInfo.InvariantCulture);

        return Enum.ToObject(typeof(T), value | mask).As<T>();
    }

    public static T Remove<T>(this Enum source, T v)
    {
        var value = Convert.ToInt32(source, CultureInfo.InvariantCulture);
        var mask = Convert.ToInt32(v, CultureInfo.InvariantCulture);

        return Enum.ToObject(typeof(T), value & ~mask).As<T>();
    }

    public static T AsEnum<T>(this string value)
    {
        try
        {
            return Enum.Parse(typeof(T), value, true).As<T>();
        }
        catch
        {
            return default(T);
        }
    }
}

With regular use of StringBuilder, you may see the need to combine AppendFormat() and AppendLine().

public static void AppendFormatLine(this StringBuilder sb, string format, params object[] args)
{
    sb.AppendFormat(format, args);
    sb.AppendLine();
}

Also, since I'm converting an application from VB6 to C#, the following are very useful to me:

public static string Left(this string s, int length)
{
    if (s.Length >= length)
        return s.Substring(0, length);
    throw new ArgumentException("Length must be less than the length of the string.");
}
public static string Right(this string s, int length)
{
    if (s.Length >= length)
        return s.Substring(s.Length - length, length);
    throw new ArgumentException("Length must be less than the length of the string.");
}

String.format should not have been static. So I use an extension method called frmt:

<Extension()> Public Function frmt(ByVal format As String,
                                   ByVal ParamArray args() As Object) As String
    If format Is Nothing Then Throw New ArgumentNullException("format")
    Return String.Format(format, args)
End Function

When I want to read or write a number to a byte stream without constructing a binary writer (technically you aren't supposed to modify the raw stream after you've wrapped it with a writer):

<Extension()> Public Function Bytes(ByVal n As ULong,
                                    ByVal byteOrder As ByteOrder,
                                    Optional ByVal size As Integer = 8) As Byte()
    Dim data As New List(Of Byte)
    Do Until data.Count >= size
        data.Add(CByte(n And CULng(&HFF)))
        n >>= 8
    Loop
    Select Case byteOrder
        Case ByteOrder.BigEndian
            Return data.ToArray.reversed
        Case ByteOrder.LittleEndian
            Return data.ToArray
        Case Else
            Throw New ArgumentException("Unrecognized byte order.")
    End Select
End Function
<Extension()> Public Function ToULong(ByVal data As IEnumerable(Of Byte),
                                      ByVal byteOrder As ByteOrder) As ULong
    If data Is Nothing Then Throw New ArgumentNullException("data")
    Dim val As ULong
    Select Case byteOrder
        Case ByteOrder.LittleEndian
            data = data.Reverse
        Case ByteOrder.BigEndian
            'no change required
        Case Else
            Throw New ArgumentException("Unrecognized byte order.")
    End Select
    For Each b In data
        val <<= 8
        val = val Or b
    Next b
    Return val
End Function

This one shifts a sequence so that you get the given item first. I used it for example to take the day of weeks and shift it so that the first day in the sequence is the first day of the week for the current culture.

    /// <summary>
    /// Shifts a sequence so that the given <paramref name="item"/> becomes the first. 
    /// Uses the specified equality <paramref name="comparer"/> to find the item.
    /// </summary>
    /// <typeparam name="TSource">Type of elements in <paramref name="source"/>.</typeparam>
    /// <param name="source">Sequence of elements.</param>
    /// <param name="item">Item which will become the first.</param>
    /// <param name="comparer">Used to find the first item.</param>
    /// <returns>A shifted sequence. For example Shift({1,2,3,4,5,6}, 3) would become {3,4,5,6,1,2}. </returns>
    public static IEnumerable<TSource> Shift<TSource>(this IEnumerable<TSource> source, TSource item, IEqualityComparer<TSource> comparer)
    {
        var queue = new Queue<TSource>();
        bool found = false;

        foreach (TSource e in source)
        {
            if (!found && comparer.Equals(item, e))
                found = true;

            if (found)
                yield return e;
            else
                queue.Enqueue(e);
        }

        while (queue.Count > 0)
            yield return queue.Dequeue();
    }


    /// <summary>
    /// Shifts a sequence so that the given item becomes the first. 
    /// Uses the default equality comparer to find the item.
    /// </summary>
    /// <typeparam name="TSource">Type of elements in <paramref name="source"/>.</typeparam>
    /// <param name="source">Sequence of elements.</param>
    /// <param name="element">Element which will become the first.</param>
    /// <returns>A shifted sequence. For example Shift({1,2,3,4,5,6}, 3) would become {3,4,5,6,1,2}. </returns>
    public static IEnumerable<TSource> Shift<TSource>(this IEnumerable<TSource> source, TSource element)
    {
        return Shift(source, element, EqualityComparer<TSource>.Default);
    }

I autopilot the following to solve the class-name-to-upper-case-url problem in MVC projects:

public static class RouteCollectionExt
{
    public static Route MapRouteLowercase(this RouteCollection routes, string name, string url, object defaults)
    {
        var route = new LowercaseRoute(url, new RouteValueDictionary(defaults), new MvcRouteHandler());

        routes.Add(name, route);

        return route;
    }

    private class LowercaseRoute : Route
    {
        public LowercaseRoute(string url, IRouteHandler routeHandler)
            : base(url, routeHandler) { }

        public LowercaseRoute(string url, RouteValueDictionary defaults, IRouteHandler routeHandler)
            : base(url, defaults, routeHandler) { }

        public LowercaseRoute(string url, RouteValueDictionary defaults, RouteValueDictionary constraints, IRouteHandler routeHandler)
            : base(url, defaults, constraints, routeHandler) { }

        public LowercaseRoute(string url, RouteValueDictionary defaults, RouteValueDictionary constraints, RouteValueDictionary dataTokens, IRouteHandler routeHandler)
            : base(url, defaults, constraints, dataTokens, routeHandler) { }

        public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
        {
            var path = base.GetVirtualPath(requestContext, values);

            if (path != null)
            {
                path.VirtualPath = path.VirtualPath.ToLowerInvariant();
            }

            return path;
        }
    }  
}

Usage:

routes.MapRouteLowercase(
  "Default",
  "{controller}/{action}/{id}",
  new { controller = "Home", action = "Index", id = "" } 
);
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string guid1 = "936DA01F-9ABD-4d9d-80C7-02AF85C822A8";
            string guid2 = "936DA01F-9ABD-4d9d-80C7-02AF85C822A";
            Console.WriteLine("guid1: {0}", guid1.IsGuid());
            Console.WriteLine("guid2: {0}", guid2.IsGuid());
            Console.ReadLine();
        }
    }

    public static class GuidUtility
    {
        /// <summary>
        /// Determines if string is legitimate GUID
        /// </summary>       
        public static Boolean IsGuid(this String s)
        {
            string pattern = @"^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$";
            Regex regex = new Regex(pattern);
            return regex.IsMatch(s);
        }
    }
}

Compare any given property of the given fileinfo class against another one..

    public static bool compare(this FileInfo F1,FileInfo F2,string propertyName)
    {
        try
        {
            System.Reflection.PropertyInfo p1 = F1.GetType().GetProperty(propertyName);
            System.Reflection.PropertyInfo p2 = F2.GetType().GetProperty(propertyName);

                if (p1.GetValue(F1, null) == p2.GetValue(F1, null))
                {
                    return true;
                }

        }
        catch (Exception ex)
        {
            return false;
        }

        return false;
    }

This is something which I often use to copy from a stream into another stream, especially for copying stuff into a MemoryStream.

public static void CopyStream(this Stream destination, Stream source)
    {
        if (source.CanSeek)
        {
            source.Position = 0;
        }
        int Length = 64000;
        Byte[] buffer = new Byte[Length];
        int bytesRead = source.Read(buffer, 0, Length);
        // write the required bytes
        while (bytesRead > 0)
        {
            destination.Write(buffer, 0, bytesRead);
            bytesRead = source.Read(buffer, 0, Length);
        }
    }

Implementation:

MemoryStream result = new MemoryStream();
Stream s = new FileStream(tempDocFile, FileMode.Open);

result.CopyStream(s);

s.Close();

In multi-threaded WPF applications (for example when you're using sockets or timers) I often have to invoke the GUI thread to change WPF Element attributes. This is ugly bloated code, especially since you need to do it for every method. That's why I made this extension method:

    /// <summary>
    /// Invoke the element's thread using a dispatcher. This is needed for changing WPF element attributes.
    /// </summary>
    /// <param name="dispatcherObject">The element of which to use the thread.</param>
    /// <param name="action">The action to do with the invoked thread.</param>
    /// <param name="dispatcherPriority">The priority of this action.</param>
    public static void DoInvoked(this System.Windows.Threading.DispatcherObject dispatcherObject, Action action, System.Windows.Threading.DispatcherPriority dispatcherPriority = System.Windows.Threading.DispatcherPriority.Render)
    {
        if (System.Threading.Thread.CurrentThread == dispatcherObject.Dispatcher.Thread)
        {
            action();
        }
        else
        {
            dispatcherObject.Dispatcher.BeginInvoke(action, dispatcherPriority, null);
        }
    }

Implementation:

public partial class MainWindow : Window
{
    ... other code ...
    void updateTime(object sender, ElapsedEventArgs e)
    {
        this.DoInvoked(() => textBoxStatus.Text = "Done.");
    }
}

I'd probably use them most for constrained types.

Something like:

public class Gallons
{
    private int m_gallons;

    public Gallons(int count)
    {
        if(count < 0)
            throw new ArgumentException("Cannot have negative gallons");
        m_gallons = count;
    }

    static public Gallons operator + (Gallons left, Gallons right)
    {
        return new Gallons(left.m_gallons + right.m_gallons);
    }
    public override string ToString()
    {
        return m_gallons.ToString();
    }
}
public class Feet
{
    private int m_feet;

    public Feet(int count)
    {
        if(count < 0)
            throw new ArgumentException("Cannot have negative feet");
        m_feet = count;
    }

    static public Feet operator +(Feet left, Feet right)
    {
        return new Feet(left.m_feet + right.m_feet);
    }
    public override string ToString()
    {
        return m_feet.ToString();
    }
}

public static class Conversions
{
    static public Feet Feet(this int i)
    {
        return new Feet(i);
    }
    static public Gallons Gallons(this int i)
    {
        return new Gallons(i);
    }
}

public class Test
{
    static public int Main(string[] args)
    {
        System.Console.WriteLine(2.Feet() + 3.Feet()); // 5
        System.Console.WriteLine(3.Gallons() + 4.Gallons()); // 7
        System.Console.WriteLine(2.Feet() + 3.Gallons()); // doesn't compile - can't add feet to gallons!
        return 0;
    }
}
Related