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

C#.NetExtension MethodsSyntactic Sugar

C# Problem Overview


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!

C# Solutions


Solution 1 - C#

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);
}

Solution 2 - C#

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

Solution 3 - C#

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.

Solution 4 - C#

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");

Solution 5 - C#

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);
			}
		}
	}

Solution 6 - C#

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.

Solution 7 - C#

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.

Solution 8 - C#

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!)

Solution 9 - C#

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.

Solution 10 - C#

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.

Solution 11 - C#

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;
    }
}

Solution 12 - C#

This is an extension method to centralize null checks before raising events.

public static class EventExtension
{
    public static void RaiseEvent<T>(this EventHandler<T> handler, object obj, T args) where T : EventArgs
    {
        EventHandler<T> theHandler = handler;

        if (theHandler != null)
        {
            theHandler(obj, args);
        }
    }
}

Solution 13 - C#

Often times, I've needed to display a user-friendly value based on an Enum value, but didn't want to go the custom Attribute route, as it didn't seem too elegant.

With this handy extension method:

public static string EnumValue(this MyEnum e) {
    switch (e) {
        case MyEnum.First:
            return "First Friendly Value";
        case MyEnum.Second:
            return "Second Friendly Value";
        case MyEnum.Third:
            return "Third Friendly Value";
    }
    return "Horrible Failure!!";
}

I can do this:

Console.WriteLine(MyEnum.First.EnumValue());

Yay!

Solution 14 - C#

This one is incredibly simple, but it's a check I do a lot so I ended up making an extension method for it. My favorite extension methods tend to be the really simple, straightforward ones like this, or like Taylor L's extension method for raising events.

public static bool IsNullOrEmpty(this ICollection e)
{
    return e == null || e.Count == 0;
}

Solution 15 - C#

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);
    }

Solution 16 - C#

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));
}

Solution 17 - C#

I am converting a lot of Java to C#. Many of the methods vary only in capitalization or other small syntax differences. So Java code such as

myString.toLowerCase();

will not compile but by adding an extension method

public static void toLowerCase(this string s)
{
    s.ToLower();
}

I can catch all the methods (and I assume a good compiler will inline this anyway?).

It's certainly made the job much easier and more reliable. (I thank @Yuriy - see answer in: https://stackoverflow.com/questions/1548296/differences-between-stringbuilder-in-java-and-c) for the suggestion.

Solution 18 - C#

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.

Solution 19 - C#

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;
}

Solution 20 - C#

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()

Solution 21 - C#

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!!

Solution 22 - C#

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

Solution 23 - C#

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.

Solution 24 - C#

There are a couple that I've mentioned here that I use:

Solution 25 - C#

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);
		}
	}
}

Solution 26 - C#

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.");
}

Solution 27 - C#

My favourite from my own personal collection of string utils is one that will parse a strongly typed value from a string for any type that has a TryParse method:

public static class StringUtils
{
    /// <summary>
    /// This method will parse a value from a string.
    /// If the string is null or not the right format to parse a valid value,
    /// it will return the default value provided.
    /// </summary>
    public static T To<t>(this string value, T defaultValue)
        where T: struct
    {
        var type = typeof(T);
        if (value != null)
        {
            var parse = type.GetMethod("TryParse", new Type[] { typeof(string), type.MakeByRefType() });
            var parameters = new object[] { value, default(T) };
            if((bool)parse.Invoke(null, parameters))
                return (T)parameters[1];
        }
        return defaultValue;
    }

    /// <summary>
    /// This method will parse a value from a string.
    /// If the string is null or not the right format to parse a valid value,
    /// it will return the default value for the type.
    /// </summary>
    public static T To<t>(this string value)
        where T : struct
    {
        return value.To<t>(default(T));
    }
}

It's great for getting strongly typed information from query strings:

var value = Request.QueryString["value"].To<int>();

Solution 28 - C#

I hate having to do this everywhere:

DataSet ds = dataLayer.GetSomeData(1, 2, 3);
if(ds != null){
    if(ds.Tables.Count > 0){
        DataTable dt = ds.Tables[0];
        foreach(DataRow dr in dt.Rows){
            //Do some processing
        }
    }
}

Instead I usually use the following Extension Method:

public static IEnumerable<DataRow> DataRows(this DataSet current){
    if(current != null){
        if(current.Tables.Count > 0){
            DataTable dt = current.Tables[0];
            foreach(DataRow dr in dt.Rows){
                yield return dr;
            }
        }
    }
}

So the first example then becomes:

foreach(DataRow row in ds.DataRows()){
    //Do some processing
}

Yay, Extension Methods!

Solution 29 - C#

Here's one I wrote recently at work and blogged about:

http://crazorsharp.blogspot.com/2009/03/cool-ienumberable-extension-method_25.html

It's basically IEnumerable.ToHtmlTable();

Solution 30 - C#

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

Solution 31 - C#

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);
    }

Solution 32 - C#

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 = "" } 
);

Solution 33 - C#

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);
        }
    }
}

Solution 34 - C#

Ever worked with Entity Framework & used a line of code similar to this over and over?

_context.EmployeeSet.Include("Department")
    .Include("Manager").Include( ... ).Select();

Isn't it easier to do this:

_context.EmployeeSet.IncludeCommonReferenceses().Select();

`

internal static class ObjectContextExtensions
{
    internal static ObjectQuery<Employee> IncludeCommonReferenceses(this ObjectQuery<Employee> employeeSet)
    {
        return employeeSet.Include(GetPropertyName<Employee>(e => e.Department))
           .Include(GetPropertyName<Employee>(e => e.Manager)).Include( ... );
    }

    private static string GetPropertyName<T>(Expression<Func<T, object>> subSelector)
    {
        return ((MemberExpression)subSelector.Body).Member.Name;
    }
}

I Recommend you save the property names in consts to avoid using reflection over & over agasin.

Solution 35 - C#

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;
    }

Solution 36 - C#

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();

Solution 37 - C#

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.");
    }
}

Solution 38 - C#

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;
    }
}

Solution 39 - C#

Some of these have already been posted but I just wanted to say that I have seen a number of these threads and the votes never match the reality of what is useful. IMO, this is the list of the truly most useful extension methods

someCollection.ForEach(i => i.DoSomething());

This is very very useful because it replaces the built in foreach statement and we all know how often that gets used.

7.CreateSequence();

This just creates a sequence from 0 to 6. There can be other versions such as specifying a starting point and step. This is the second most useful function because it replaces the for loop. Some people have said that this duplicates the Enumerable.Range function, which is true, but one of the things I like with linq is the left to right ordering, so you can do something like this

myCollection.Where(i => i.Something == somethingElse).Count().CreateSequence(). do something else

The next most useful is the CastTo and As. Again they duplicate built in functionality but they preserve the left to right ordering. Note that CastTo is different to Cast in that CastTo works on a single object.

myObject.CastTo<Person>().DoSomething()
myObject.As<Person>()

Then there is the SplitAsEnumerable. This works the same as split but doesn't load everything into memory at once. This is great for parsing large files. It works on a string or a stream.

myFileStream.SplitAsEnumerable("\r\n").Select(line => line.SplitAsEnumerable(","))

The last one is a way to turn a collection into a string. This is great for displaying stuff on the screen or writing to files. eg:

myTextBox.Text = "Top 3 scorers are " + myCollection.OrderBy(i => i.Score).Take(3).FlattenToString(i => i.Score.ToString(), ", ");

Solution 40 - C#

Whilst I did not write these two - I wish I had. Found on http://lostechies.com/jimmybogard/2009/10/16/more-missing-linq-operators/

Append

public static IEnumerable<TSource> Append<TSource>(this IEnumerable<TSource> source, TSource element)
{
    using (IEnumerator<TSource> e1 = source.GetEnumerator())
        while (e1.MoveNext())
            yield return e1.Current;

    yield return element;
}

Prepend

public static IEnumerable<TSource> Prepend<TSource>(this IEnumerable<TSource> source, TSource element)
{
    yield return element;

    using (IEnumerator<TSource> e1 = source.GetEnumerator())
        while (e1.MoveNext())
            yield return e1.Current;
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMark CarpenterView Question on Stackoverflow
Solution 1 - C#TalljoeView Answer on Stackoverflow
Solution 2 - C#JoshView Answer on Stackoverflow
Solution 3 - C#EnigmativityView Answer on Stackoverflow
Solution 4 - C#John FarrellView Answer on Stackoverflow
Solution 5 - C#rmooreView Answer on Stackoverflow
Solution 6 - C#geofftnzView Answer on Stackoverflow
Solution 7 - C#Michael HarenView Answer on Stackoverflow
Solution 8 - C#geofftnzView Answer on Stackoverflow
Solution 9 - C#Thomas LevesqueView Answer on Stackoverflow
Solution 10 - C#ThorarinView Answer on Stackoverflow
Solution 11 - C#jristaView Answer on Stackoverflow
Solution 12 - C#Taylor LeeseView Answer on Stackoverflow
Solution 13 - C#Mark CarpenterView Answer on Stackoverflow
Solution 14 - C#SternoView Answer on Stackoverflow
Solution 15 - C#eulerfxView Answer on Stackoverflow
Solution 16 - C#eulerfxView Answer on Stackoverflow
Solution 17 - C#peter.murray.rustView Answer on Stackoverflow
Solution 18 - C#Robert HarveyView Answer on Stackoverflow
Solution 19 - C#geofftnzView Answer on Stackoverflow
Solution 20 - C#okutaneView Answer on Stackoverflow
Solution 21 - C#BFreeView Answer on Stackoverflow
Solution 22 - C#andyView Answer on Stackoverflow
Solution 23 - C#SvishView Answer on Stackoverflow
Solution 24 - C#KeithView Answer on Stackoverflow
Solution 25 - C#Mike GeiseView Answer on Stackoverflow
Solution 26 - C#opedogView Answer on Stackoverflow
Solution 27 - C#HelephantView Answer on Stackoverflow
Solution 28 - C#Mark CarpenterView Answer on Stackoverflow
Solution 29 - C#BFreeView Answer on Stackoverflow
Solution 30 - C#Craig GidneyView Answer on Stackoverflow
Solution 31 - C#SvishView Answer on Stackoverflow
Solution 32 - C#annakataView Answer on Stackoverflow
Solution 33 - C#John GroveView Answer on Stackoverflow
Solution 34 - C#HuBeZaView Answer on Stackoverflow
Solution 35 - C#RameshVelView Answer on Stackoverflow
Solution 36 - C#JensView Answer on Stackoverflow
Solution 37 - C#user287529View Answer on Stackoverflow
Solution 38 - C#kyoryuView Answer on Stackoverflow
Solution 39 - C#MikeKullsView Answer on Stackoverflow
Solution 40 - C#KaneView Answer on Stackoverflow