478
votes

Let's make a list of answers where you post your excellent and favorite extension methods.

The requirement is that the full code must be posted and a example and an explanation on how to use it.

Based on the high interest in this topic I have setup an Open Source Project called extensionoverflow on Codeplex.

Please mark your answers with an acceptance to put the code in the Codeplex project.

Please post the full sourcecode and not a link.

Codeplex News:

24.08.2010 The Codeplex page is now here: http://extensionoverflow.codeplex.com/

11.11.2008 XmlSerialize / XmlDeserialize is now Implemented and Unit Tested.

11.11.2008 There is still room for more developers. ;-) Join NOW!

11.11.2008 Third contributer joined ExtensionOverflow, welcome to BKristensen

11.11.2008 FormatWith is now Implemented and Unit Tested.

09.11.2008 Second contributer joined ExtensionOverflow. welcome to chakrit.

09.11.2008 We need more developers. ;-)

09.11.2008 ThrowIfArgumentIsNull in now Implemented and Unit Tested on Codeplex.

4
  • Now the first code is committed to the Codeplex site. Commented Nov 7, 2008 at 20:13
  • Erik unfortunately everything is started now on codeplex. Please join anyway. Commented Nov 11, 2008 at 22:43
  • 3
    Looks pretty good. I do have a comment about naming the static classes. Naming them <type>Extensions isn't very informative. For example StringExtensions holds both formatting and xml stuff. I think it's better to name the class with why you're extending that type. For example UnixDateTimeConversions. You can reasonably guess it holds methods for converting to and from Unix time. Just a thought! Commented Aug 26, 2010 at 15:56
  • Check this URL for more about C# Extension Methods planetofcoders.com/c-extension-methods Commented Mar 9, 2012 at 5:59

150 Answers 150

1
2 3 4 5
232
votes
public static bool In<T>(this T source, params T[] list)
{
  if(null==source) throw new ArgumentNullException("source");
  return list.Contains(source);
}

Allows me to replace:

if(reallyLongIntegerVariableName == 1 || 
    reallyLongIntegerVariableName == 6 || 
    reallyLongIntegerVariableName == 9 || 
    reallyLongIntegerVariableName == 11)
{
  // do something....
}

and

if(reallyLongStringVariableName == "string1" || 
    reallyLongStringVariableName == "string2" || 
    reallyLongStringVariableName == "string3")
{
  // do something....
}

and

if(reallyLongMethodParameterName == SomeEnum.Value1 || 
    reallyLongMethodParameterName == SomeEnum.Value2 || 
    reallyLongMethodParameterName == SomeEnum.Value3 || 
    reallyLongMethodParameterName == SomeEnum.Value4)
{
  // do something....
}

With:

if(reallyLongIntegerVariableName.In(1,6,9,11))
{
      // do something....
}

and

if(reallyLongStringVariableName.In("string1","string2","string3"))
{
      // do something....
}

and

if(reallyLongMethodParameterName.In(SomeEnum.Value1, SomeEnum.Value2, SomeEnum.Value3, SomeEnum.Value4)
{
  // do something....
}
Sign up to request clarification or add additional context in comments.

12 Comments

Well it compiles if you're using System.Linq;
Maybe "EqualsAnyOf" would be a better name than "In"?
I'm not sure I like it - I like the brevity of In, but maybe IsIn would be better.
Using the same Contains method: (new[] { 1, 2, 3 }).Contains(a)
I thought of In<T>(...) as well and found it to be the most useful extension method outside of the standard library. But I am at odds with the name In. A method name is supposed to be describing what it does, but In doesn't do so. I've called it IsAnyOf<T>(...), but I guess IsIn<T>(...) would be adequate as well.
|
160
votes

I have various extension methods in my MiscUtil project (full source is available there - I'm not going to repeat it here). My favourites, some of which involve other classes (such as ranges):

Date and time stuff - mostly for unit tests. Not sure I'd use them in production :)

var birthday = 19.June(1976);
var workingDay = 7.Hours() + 30.Minutes();

Ranges and stepping - massive thanks to Marc Gravell for his operator stuff to make this possible:

var evenNaturals = 2.To(int.MaxValue).Step(2);
var daysSinceBirth = birthday.To(DateTime.Today).Step(1.Days());

Comparisons:

var myComparer = ProjectionComparer.Create(Person p => p.Name);
var next = myComparer.ThenBy(p => p.Age);
var reversed = myComparer.Reverse();

Argument checking:

x.ThrowIfNull("x");

LINQ to XML applied to anonymous types (or other types with appropriate properties):

// <Name>Jon</Name><Age>32</Age>
new { Name="Jon", Age=32}.ToXElements();
// Name="Jon" Age="32" (as XAttributes, obviously)
new { Name="Jon", Age=32}.ToXAttributes()

Push LINQ - would take too long to explain here, but search for it.

13 Comments

That's nice! You should put it up on Google Code or CodePlex so I can send you some patches :-) I promise it'll be readable :-P
@bovium: You can already see the code. Follow the link in the first sentence - full source is there.
@bovium: I'd rather do it myself, putting it on code.google.com and manage the project myself, if you don't mind. Obviously you're within the licence to put it on Codeplex if you keep the appropriate attribution, but I'd rather sort it out myself soon unless you're desperate :)
@Jon Skeet. Its put under the MIT license free of use for everybody. Commercially or open source. Why not join forces and make an extension methods library for the public.
Just because I do lots of other bits and pieces in that library. You're welcome to take a copy of it all for your project, but I'd rather keep one copy in my own project too.
|
147
votes

string.Format shortcut:

public static class StringExtensions
{
    // Enable quick and more natural string.Format calls
    public static string F(this string s, params object[] args)
    {
        return string.Format(s, args);
    }
}

Example:

var s = "The co-ordinate is ({0}, {1})".F(point.X, point.Y);

For quick copy-and-paste go here.

Don't you find it more natural to type "some string".F("param") instead of string.Format("some string", "param") ?

For a more readable name, try one of these suggestion:

s = "Hello {0} world {1}!".Fmt("Stack", "Overflow");
s = "Hello {0} world {1}!".FormatBy("Stack", "Overflow");
s = "Hello {0} world {1}!".FormatWith("Stack", "Overflow");
s = "Hello {0} world {1}!".Display("Stack", "Overflow");
s = "Hello {0} world {1}!".With("Stack", "Overflow");

..

20 Comments

It's certainly short - but will be unreadable to any new members of your team.
I think readability matters more in the grander scheme of your code than a few shorthand statements that could be quickly looked up/asked.
Personally I'd like a separate Formatter object, which the BCL could parse the pattern of once and reuse. That would increase readability and performance. I've asked the BCL team - we'll see...
It's an extension method, of course it's going to be unreadable to new members of the team. I thought that was the idea with this witty stuff? How else will the new members know how clever we are?
Ok... I just went to put this into action and went with .With -- so you get "This is a {0}".With("test") and it's very readable and makes sense. FYI
|
89
votes

Are these any use?

public static bool CoinToss(this Random rng)
{
    return rng.Next(2) == 0;
}

public static T OneOf<T>(this Random rng, params T[] things)
{
    return things[rng.Next(things.Length)];
}

Random rand;
bool luckyDay = rand.CoinToss();
string babyName = rand.OneOf("John", "George", "Radio XBR74 ROCKS!");

3 Comments

this mimicks pythons random.choice(seq) function. nice.
Couple things: I'd recommend that OneOf should accept any IList<T>. Then you could always also have an overload that takes a params arg and just passes that into the IList<T> overload. I gave an answer (way down at the bottom right now) with a NextBool method similar to your CoinToss, but with an overload that takes a probability parameter (what if I want something to happen 75% of the time?). Also, just a nit pick: your example code will throw a NullReferenceException since rand is never initialized.
+1 I really like this, but I prefer CoinToss to be implemented with rng.NextDouble() < .5 because internally .Next(int) is made with .NextDouble() so you would save a cast, a * and a check.
76
votes
public static class ComparableExtensions
{
  public static bool Between<T>(this T actual, T lower, T upper) where T : IComparable<T>
  {
    return actual.CompareTo(lower) >= 0 && actual.CompareTo(upper) < 0;
  }
}

Example:

if (myNumber.Between(3,7))
{
  // ....
}

13 Comments

I love this one but I'm trying to decide if it's right to make the bounds check inclusive on the min value but exclusive on the max value. I wonder if that would be confusing. 5.Between(5,10) is true but 5.Between(1,5) is false. Not even sure that a companion Within method would help. Thougts?
Wouldn't the name "IsBetween" make more sense? Also maybe make an IsBetweenInclusive and IsBetweenExclusive. No idea which one to take for default though.
@Steve: it makes more sense if it were a datetime extension.
To me between implies: 5.Between(5,10) returns false, and 10.Between(5,10) returns false as well. That just feels natural to me.
It seems to me that multiple people have different ideas as to what is natural. Because of this it probably should be explicitly stated what is being used (ie Inclusive vs Exclusive), as this could be a very easy source of errors.
|
58
votes

The extension method:

public static void AddRange<T, S>(this ICollection<T> list, params S[] values)
    where S : T
{
    foreach (S value in values)
        list.Add(value);
}

The method applies for all types and lets you add a range of items to a list as parameters.

Example:

var list = new List<Int32>();
list.AddRange(5, 4, 8, 4, 2);

11 Comments

Would be better as this IList<T>
Just use collection initializer => var list = new List<int>{5,4,8,4,2};
Why not just calling List<T>.AddRange(IEnumerable<T> collection) within your method?
@Will: Actually, it would be best to accept an ICollection<T>; then it could also be used on, for example, LinkedList<T> and HashSet<T>, not just indexed collections.
Edited to allow covariance in pre-.net 4.0
|
55
votes

By all means put this in the codeplex project.

Serializing / Deserializing objects to XML:

/// <summary>Serializes an object of type T in to an xml string</summary>
/// <typeparam name="T">Any class type</typeparam>
/// <param name="obj">Object to serialize</param>
/// <returns>A string that represents Xml, empty otherwise</returns>
public static string XmlSerialize<T>(this T obj) where T : class, new()
{
    if (obj == null) throw new ArgumentNullException("obj");

    var serializer = new XmlSerializer(typeof(T));
    using (var writer = new StringWriter())
    {
        serializer.Serialize(writer, obj);
        return writer.ToString();
    }
}

/// <summary>Deserializes an xml string in to an object of Type T</summary>
/// <typeparam name="T">Any class type</typeparam>
/// <param name="xml">Xml as string to deserialize from</param>
/// <returns>A new object of type T is successful, null if failed</returns>
public static T XmlDeserialize<T>(this string xml) where T : class, new()
{
    if (xml == null) throw new ArgumentNullException("xml");

    var serializer = new XmlSerializer(typeof(T));
    using (var reader = new StringReader(xml))
    {
        try { return (T)serializer.Deserialize(reader); }
        catch { return null; } // Could not be deserialized to this type.
    }
}

12 Comments

I'd be tempted to call the first one ToXml() (like ToString())
Apologies to the OP if he intentionally wrote it this way, but the use of MemoryStreams AND XmlReader/XmlWriter was overkill. The StringReader and StringWriter class are perfect for this operation.
Beware, this is not threadsafe. You should definitely synchronize your access to the static serialisers dictionary.
@Yann, @T, It's much easier if you just add the "thread static" attribute. Then a new cache will be created per thread. No need for synchronization.
@Jonathan C Dickinson: It appears from the MSDN docs here msdn.microsoft.com/en-us/library/… that the constructor that is used (new XmlSerializer(type)) does not have a memory leak problem. So maybe the caching code isn't needed?
|
46
votes

ForEach for IEnumerables

public static class FrameworkExtensions
{
    // a map function
    public static void ForEach<T>(this IEnumerable<T> @enum, Action<T> mapFunction)
    {
        foreach (var item in @enum) mapFunction(item);
    }
}

Naive example:

var buttons = GetListOfButtons() as IEnumerable<Button>;

// click all buttons
buttons.ForEach(b => b.Click());

Cool example:

// no need to type the same assignment 3 times, just
// new[] up an array and use foreach + lambda
// everything is properly inferred by csc :-)
new { itemA, itemB, itemC }
    .ForEach(item => {
        item.Number = 1;
        item.Str = "Hello World!";
    });

Note:

This is not like Select because Select expects your function to return something as for transforming into another list.

ForEach simply allows you to execute something for each of the items without any transformations/data manipulation.

I made this so I can program in a more functional style and I was surprised that List has a ForEach while IEnumerable does not.

Put this in the codeplex project

11 Comments

Post on why LINQ's IEnumerable<T> extensions don't include a ForEach: stackoverflow.com/questions/317874/…
I recommend reading this before using method: blogs.msdn.com/ericlippert/archive/2009/05/18/…
@jpbochi: This is just Microsoft demagogy
@abatishchev And your comment is just prejudice against Microsoft. It does not invalidade any word written by Eric. Someone's arguments are not made valid or invalid just because of the company he/she works for.
By the way, let me make one point clear. I didn't say you should not use this ForEach extension method. I just said that you should consider the points that Eric exposed before you decide whether to use it or not. I read it and I decided not to use it. You're free to do whatever you want with your code.
|
43
votes

My conversion extensions which allow you to do:

int i = myString.To<int>();

Here it is, as posted on TheSoftwareJedi.com

public static T To<T>(this IConvertible obj)
{
  return (T)Convert.ChangeType(obj, typeof(T));
}

public static T ToOrDefault<T>
             (this IConvertible obj)
{
    try
    {
        return To<T>(obj);
    }
    catch
    {
        return default(T);
    }
}

public static bool ToOrDefault<T>
                    (this IConvertible obj,
                     out T newObj)
{
    try
    {
        newObj = To<T>(obj); 
        return true;
    }
    catch
    {
        newObj = default(T); 
        return false;
    }
}

public static T ToOrOther<T>
                       (this IConvertible obj,
                       T other)
{
  try
  {
      return To<T>obj);
  }
  catch
  {
      return other;
  }
}

public static bool ToOrOther<T>
                         (this IConvertible obj,
                         out T newObj,
                         T other)
{
    try
    {
        newObj = To<T>(obj);
        return true;
    }
    catch
    {
        newObj = other;
        return false;
    }
}

public static T ToOrNull<T>
                      (this IConvertible obj)
                      where T : class
{
    try
    {
        return To<T>(obj);
    }
    catch
    {
        return null;
    }
}

public static bool ToOrNull<T>
                  (this IConvertible obj,
                  out T newObj)
                  where T : class
{
    try
    {
        newObj = To<T>(obj);
        return true;
    }
    catch
    {
        newObj = null;
        return false;
    }
}

You can ask for default (calls blank constructor or "0" for numerics) on failure, specify a "default" value (I call it "other"), or ask for null (where T : class). I've also provided both silent exception models, and a typical TryParse model that returns a bool indicating the action taken, and an out param holds the new value. So our code can do things like this

int i = myString.To<int>();
string a = myInt.ToOrDefault<string>();
//note type inference
DateTime d = myString.ToOrOther(DateTime.MAX_VALUE);
double d;
//note type inference
bool didItGiveDefault = myString.ToOrDefault(out d);
string s = myDateTime.ToOrNull<string>();

I couldn't get Nullable types to roll into the whole thing very cleanly. I tried for about 20 minutes before I threw in the towel.

5 Comments

Personally, i'm not a fan of code that does try / catch to determine the outcome. Try / catch should be used for errors that occur outside of the intended logic, IMO. hmmmmm
If I didn't want you to use the code, I wouldn't have posted it! :)
Finally something unseen. I like it. :)
You should at least change that "catch" clause to only catch those exceptions that ChangeType() will raise when it cannot "convert" the reference. I think you wouldn't want to have any OutOfMemoryException, ExecutionEngineException, ThreadAbortException, or alike being treated as a conversion error. Those things will otherwise be pretty hard to track errors.
I believe ToOrNull has the exact same behavior as ToOrDefault (i.e., if you call ToOrDefault on a reference type with an unsuccessful conversion, it will return null). But more importantly, it seems kind of redundant to me since var s = myObject as string accomplishes the same thing as var s = myObject.ToOrNull<string>() -- but without potentially having to catch an InvalidCastException. Am I missing something?
43
votes

I have an extension method for logging exceptions:

public static void Log(this Exception obj)
{
  //your logging logic here
}

And it is used like this:

try
{
    //Your stuff here
}
catch(Exception ex)
{
    ex.Log();
}

[sorry for posting twice; the 2nd one is better designed :-)]

2 Comments

Should read public static void Log(this Exception obj){} maybe?
I think this is good for BCL or 3rd party exceptions, but if you roll your own exception types, you can place logging in your base exception class. That way you don't have to remember to call Log().
38
votes
public static class StringExtensions {

    /// <summary>
    /// Parses a string into an Enum
    /// </summary>
    /// <typeparam name="T">The type of the Enum</typeparam>
    /// <param name="value">String value to parse</param>
    /// <returns>The Enum corresponding to the stringExtensions</returns>
    public static T EnumParse<T>(this string value) {
        return StringExtensions.EnumParse<T>(value, false);
    }

    public static T EnumParse<T>(this string value, bool ignorecase) {

        if (value == null) {
            throw new ArgumentNullException("value");
        }

        value = value.Trim();

        if (value.Length == 0) {
            throw new ArgumentException("Must specify valid information for parsing in the string.", "value");
        }

        Type t = typeof(T);

        if (!t.IsEnum) {
            throw new ArgumentException("Type provided must be an Enum.", "T");
        }

        return (T)Enum.Parse(t, value, ignorecase);
    }
}

Useful to parse a string into an Enum.

public enum TestEnum
{
    Bar,
    Test
}

public class Test
{
    public void Test()
    {
        TestEnum foo = "Test".EnumParse<TestEnum>();
    }
 }

Credit goes to Scott Dorman

--- Edit for Codeplex project ---

I have asked Scott Dorman if he would mind us publishing his code in the Codeplex project. This is the reply I got from him:

Thanks for the heads-up on both the SO post and the CodePlex project. I have upvoted your answer on the question. Yes, the code is effectively in the public domain currently under the CodeProject Open License (http://www.codeproject.com/info/cpol10.aspx).

I have no problems with this being included in the CodePlex project, and if you want to add me to the project (username is sdorman) I will add that method plus some additional enum helper methods.

5 Comments

This enum-parsing scenario comes up all the time... gotta put this in my lib :-)
Wow, I've been writing methods to map strings to enums (just started using .NET). Thanks, this will absolutely help!
You might also consider naming this ToEnum<>(), since it comes after the object.
Note that Enum.TryParse<T> has been added to Net 4.0 - blogs.msdn.com/bclteam
I don't think this method should use Trim. Trimming the input should be the responsibility of the caller.
32
votes

I find this one pretty useful:

public static class PaulaBean
{
    private static String paula = "Brillant";
    public static String GetPaula<T>(this T obj) {
        return paula;
    }
}

You may use it on CodePlex.

2 Comments

Can someone be kind enough to explain it to the less gifted of us?
hahaha Just read the article (Joel's comment above) - funny true, but having been in pretty much the same boat (on the recieving end, not the Paula end) it's only funny looking back! Once had a contractor brought in to work on a project I was designigner/lead dev on - she was not under my direct control, but was assigned work from my teams work list. Bosses lauded her as being brilliant (even hiring her again later as a Dev Lead!). It never dawned on them that every piece of code she wrote or designed had not made it to production and all had to be completely rewritten from scratch by my team!
31
votes

DateTimeExtensions

Examples:

DateTime firstDayOfMonth = DateTime.Now.First();
DateTime lastdayOfMonth = DateTime.Now.Last();
DateTime lastFridayInMonth = DateTime.Now.Last(DayOfWeek.Friday);
DateTime nextFriday = DateTime.Now.Next(DayOfWeek.Friday);
DateTime lunchTime = DateTime.Now.SetTime(11, 30);
DateTime noonOnFriday = DateTime.Now.Next(DayOfWeek.Friday).Noon();
DateTime secondMondayOfMonth = DateTime.Now.First(DayOfWeek.Monday).Next(DayOfWeek.Monday).Midnight();

4 Comments

I'd suggest renaming "SetTime" to "WithTime" as it's not actually setting it in the existing value. Nice otherwise though.
DateTime.Now.First() - first what? It's only apparent from the sample code.
Very nice. But agree that the names could be a lot better.
DateTime.Now.First will be clear enough in Intellisense if the method is well-documented.
29
votes

gitorious.org/cadenza is a full library of some of the most useful extension methods I've seen.

2 Comments

12 fairly basic extension methods. I'm a bit underwhelmed by mono-rocks.
(I'm talking about the released version, not the one you need to use source-control to get)
28
votes

Here is one I use frequently for presentation formatting.

public static string ToTitleCase(this string mText)
{
    if (mText == null) return mText;

    System.Globalization.CultureInfo cultureInfo = System.Threading.Thread.CurrentThread.CurrentCulture;
    System.Globalization.TextInfo textInfo = cultureInfo.TextInfo;

    // TextInfo.ToTitleCase only operates on the string if is all lower case, otherwise it returns the string unchanged.
    return textInfo.ToTitleCase(mText.ToLower());
}

1 Comment

Whoah, Pokemon exception handling is gonna hide issues like ThreadAbortException, etc. Please catch something specific.
28
votes

Here's a to-and-from for Roman numerals. Not often used, but could be handy. Usage:

if ("IV".IsValidRomanNumeral())
{
   // Do useful stuff with the number 4.
}

Console.WriteLine("MMMDCCCLXXXVIII".ParseRomanNumeral());
Console.WriteLine(3888.ToRomanNumeralString());

The source:

    public static class RomanNumeralExtensions
    {
        private const int NumberOfRomanNumeralMaps = 13;

        private static readonly Dictionary<string, int> romanNumerals =
            new Dictionary<string, int>(NumberOfRomanNumeralMaps)
            {
                { "M", 1000 }, 
                { "CM", 900 }, 
                { "D", 500 }, 
                { "CD", 400 }, 
                { "C", 100 }, 
                { "XC", 90 }, 
                { "L", 50 }, 
                { "XL", 40 }, 
                { "X", 10 }, 
                { "IX", 9 }, 
                { "V", 5 }, 
                { "IV", 4 }, 
                { "I", 1 }
            };

        private static readonly Regex validRomanNumeral = new Regex(
            "^(?i:(?=[MDCLXVI])((M{0,3})((C[DM])|(D?C{0,3}))"
            + "?((X[LC])|(L?XX{0,2})|L)?((I[VX])|(V?(II{0,2}))|V)?))$", 
            RegexOptions.Compiled);

        public static bool IsValidRomanNumeral(this string value)
        {
            return validRomanNumeral.IsMatch(value);
        }

        public static int ParseRomanNumeral(this string value)
        {
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }

            value = value.ToUpperInvariant().Trim();

            var length = value.Length;

            if ((length == 0) || !value.IsValidRomanNumeral())
            {
                throw new ArgumentException("Empty or invalid Roman numeral string.", "value");
            }

            var total = 0;
            var i = length;

            while (i > 0)
            {
                var digit = romanNumerals[value[--i].ToString()];

                if (i > 0)
                {
                    var previousDigit = romanNumerals[value[i - 1].ToString()];

                    if (previousDigit < digit)
                    {
                        digit -= previousDigit;
                        i--;
                    }
                }

                total += digit;
            }

            return total;
        }

        public static string ToRomanNumeralString(this int value)
        {
            const int MinValue = 1;
            const int MaxValue = 3999;

            if ((value < MinValue) || (value > MaxValue))
            {
                throw new ArgumentOutOfRangeException("value", value, "Argument out of Roman numeral range.");
            }

            const int MaxRomanNumeralLength = 15;
            var sb = new StringBuilder(MaxRomanNumeralLength);

            foreach (var pair in romanNumerals)
            {
                while (value / pair.Value > 0)
                {
                    sb.Append(pair.Key);
                    value -= pair.Value;
                }
            }

            return sb.ToString();
        }
    }

1 Comment

That reminds me of the Python PEP 313, which was an April Fools joke to include Roman Numeral literals in python: python.org/dev/peps/pep-0313
25
votes

A convenient way to deal with sizes:

public static class Extensions {
    public static int K(this int value) {
        return value * 1024;
    }
    public static int M(this int value) {
        return value * 1024 * 1024;
    }
}

public class Program {
    public void Main() {
        WSHttpContextBinding serviceMultipleTokenBinding = new WSHttpContextBinding() {
            MaxBufferPoolSize = 2.M(), // instead of 2097152
            MaxReceivedMessageSize = 64.K(), // instead of 65536
        };
    }
}

1 Comment

In my opinion this is really poor coding style. Constants should be used instead, not obfuscated logic.
24
votes

For Winform Controls:

/// <summary>
/// Returns whether the function is being executed during design time in Visual Studio.
/// </summary>
public static bool IsDesignTime(this Control control)
{
    if (LicenseManager.UsageMode == LicenseUsageMode.Designtime)
    {
        return true;
    }

    if (control.Site != null && control.Site.DesignMode)
    {
        return true;
    }

    var parent = control.Parent;
    while (parent != null)
    {
        if (parent.Site != null && parent.Site.DesignMode)
        {
            return true;
        }
        parent = parent.Parent;
    }
    return false;
}

/// <summary>
/// Sets the DropDownWidth to ensure that no item's text is cut off.
/// </summary>
public static void SetDropDownWidth(this ComboBox comboBox)
{
    var g = comboBox.CreateGraphics();
    var font = comboBox.Font;
    float maxWidth = 0;

    foreach (var item in comboBox.Items)
    {
        maxWidth = Math.Max(maxWidth, g.MeasureString(item.ToString(), font).Width);
    }

    if (comboBox.Items.Count > comboBox.MaxDropDownItems)
    {
        maxWidth += SystemInformation.VerticalScrollBarWidth;
    }

    comboBox.DropDownWidth = Math.Max(comboBox.Width, Convert.ToInt32(maxWidth));
}

IsDesignTime Usage:

public class SomeForm : Form
{
    public SomeForm()
    {
        InitializeComponent();

        if (this.IsDesignTime())
        {
            return;
        }

        // Do something that makes the visual studio crash or hang if we're in design time,
        // but any other time executes just fine
    }
}

SetDropdownWidth Usage:

ComboBox cbo = new ComboBox { Width = 50 };
cbo.Items.Add("Short");
cbo.Items.Add("A little longer");
cbo.Items.Add("Holy cow, this is a really, really long item. How in the world will it fit?");
cbo.SetDropDownWidth();

I forgot to mention, feel free to use these on Codeplex...

1 Comment

As mentioned, this is for WinForms only. It may work with WPF but there are issues (described in the comment about WPF at msdn.microsoft.com/en-us/library/…). The best solution for WPF I've found is described in geekswithblogs.net/lbugnion/archive/2009/09/05/… (though, as it's a static property, it does not really work as an extension method.)
23
votes

The ThrowIfArgumentIsNull is a nice way to do that null check we all should do.

public static class Extensions
{
    public static void ThrowIfArgumentIsNull<T>(this T obj, string parameterName) where T : class
    {
        if (obj == null) throw new ArgumentNullException(parameterName + " not allowed to be null");
    }
}

Below is the way to use it and it works on all classes in your namespace or wherever you use the namespace its within.

internal class Test
{
    public Test(string input1)
    {
        input1.ThrowIfArgumentIsNull("input1");
    }
}

It's ok to use this code on the CodePlex project.

6 Comments

I like this too, Jon has it in his, and I use something similar from Umbrella, could stand to drop "ArgumentIs" part.
Yeah! this is a kewl extension method too :)
If you use the ArgumentNullException-constructor with only 1 string-argument, that argument has to be just the parameter name, and not the error message. So your code should look like this: if (obj == null) throw new ArgumentNullException(parameterName);
I'd use default(T) for this and remove the class requirement.
@Joel: Non-default values for native types are legitimate arguments more often than null values. Checking against null makes more sense to me than checking against default. Of course, I just generalize the whole idea by saying Require.ThatArgument(input != null) or Require.ThatArgument(personId > 0). It doesn't take that much more code, it's a lot more flexible, and it reads nicely. I have additional overrides that take funcs for when you want to customize the error message or the exception itself.
|
22
votes

I miss the Visual Basic's With statement when moving to C#, so here it goes:

public static void With<T>(this T obj, Action<T> act) { act(obj); }

And here's how to use it in C#:

someVeryVeryLonggggVariableName.With(x => {
    x.Int = 123;
    x.Str = "Hello";
    x.Str2 = " World!";
});

Saves a lot of typing!

Compare this to:

someVeryVeryLonggggVariableName.Int = 123;
someVeryVeryLonggggVariableName.Str = "Hello";
someVeryVeryLonggggVariableName.Str2 = " World!";

put in codeplex project

10 Comments

Just a guess, but think about what happens if your T is a struct.
I also use the c# 3.0 property initializer syntax wherever possible to achieve the same result.
@chakrit, here's an example. It only applies when creating the object Button n = new Button { Name = "Button1", Width = 100, Height = 20, Enabled = true };
This would be useful for when you have a lot of events to hook up, because C#'s property initializer syntax doesn't support events.
this is also userful outside of property initializers, because you can only use them when creating a new object. this extension can work on previously created objects.
|
18
votes

Takes a camelCaseWord or PascalCaseWord and "wordifies" it, ie camelCaseWord => camel Case Word

public static string Wordify( this string camelCaseWord )
{
    // if the word is all upper, just return it
    if( !Regex.IsMatch( camelCaseWord, "[a-z]" ) )
        return camelCaseWord;

    return string.Join( " ", Regex.Split( camelCaseWord, @"(?<!^)(?=[A-Z])" ) );
}

I often use it in conjuction with Capitalize

public static string Capitalize( this string word )
{
    return word[0].ToString( ).ToUpper( ) + word.Substring( 1 );
}

Example usage

SomeEntityObject entity = DataAccessObject.GetSomeEntityObject( id );
List<PropertyInfo> properties = entity.GetType().GetPublicNonCollectionProperties( );

// wordify the property names to act as column headers for an html table or something
List<string> columns = properties.Select( p => p.Name.Capitalize( ).Wordify( ) ).ToList( );

Free to use in codeplex project

1 Comment

The Aggregate in Capitalize is pretty bad for performance, because it creates many string instances. Why not use word.Substring(1) instead ?
17
votes

I found this one helpful

public static IEnumerable<T> EmptyIfNull<T>(this IEnumerable<T> pSeq)
{
    return pSeq ?? Enumerable.Empty<T>();
}

It removes the null check in the calling code. You could now do

MyList.EmptyIfNull().Where(....)

1 Comment

Yes, if someone forgot "Null Object Pattern" this method is useful to patch it. Collection should never be null.
16
votes

Convert a double to string formatted using the specified culture:

public static class ExtensionMethods 
{
  public static string ToCurrency(this double value, string cultureName)
  {
    CultureInfo currentCulture = new CultureInfo(cultureName);
    return (string.Format(currentCulture, "{0:C}", value));
  }
}

Example:

double test = 154.20;
string testString = test.ToCurrency("en-US"); // $154.20

2 Comments

You should use Decimal for currency else you'll get rounding issues
What about use an Enum in the parameter instead of plain string
15
votes

Below is an extension method that adapts Rick Strahl's code (and the comments too) to stop you having to guess or read the byte order mark of a byte array or text file each time you convert it to a string.

The snippet allows you to simply do:

byte[] buffer = File.ReadAllBytes(@"C:\file.txt");
string content = buffer.GetString();

If you find any bugs please add to the comments. Feel free to include it in the Codeplex project.

public static class Extensions
{
    /// <summary>
    /// Converts a byte array to a string, using its byte order mark to convert it to the right encoding.
    /// Original article: http://www.west-wind.com/WebLog/posts/197245.aspx
    /// </summary>
    /// <param name="buffer">An array of bytes to convert</param>
    /// <returns>The byte as a string.</returns>
    public static string GetString(this byte[] buffer)
    {
        if (buffer == null || buffer.Length == 0)
            return "";

        // Ansi as default
        Encoding encoding = Encoding.Default;       

        /*
            EF BB BF    UTF-8 
            FF FE UTF-16    little endian 
            FE FF UTF-16    big endian 
            FF FE 00 00 UTF-32, little endian 
            00 00 FE FF UTF-32, big-endian 
         */

        if (buffer[0] == 0xef && buffer[1] == 0xbb && buffer[2] == 0xbf)
            encoding = Encoding.UTF8;
        else if (buffer[0] == 0xfe && buffer[1] == 0xff)
            encoding = Encoding.Unicode;
        else if (buffer[0] == 0xfe && buffer[1] == 0xff)
            encoding = Encoding.BigEndianUnicode; // utf-16be
        else if (buffer[0] == 0 && buffer[1] == 0 && buffer[2] == 0xfe && buffer[3] == 0xff)
            encoding = Encoding.UTF32;
        else if (buffer[0] == 0x2b && buffer[1] == 0x2f && buffer[2] == 0x76)
            encoding = Encoding.UTF7;

        using (MemoryStream stream = new MemoryStream())
        {
            stream.Write(buffer, 0, buffer.Length);
            stream.Seek(0, SeekOrigin.Begin);
            using (StreamReader reader = new StreamReader(stream, encoding))
            {
                return reader.ReadToEnd();
            }
        }
    }
}

2 Comments

Very usefull method, but I don't think it should be and extension method.
If you're writing a text editor it probably warrants an extension method, but I agree most of the time it's probably no more than a static private method
15
votes

Here's one I just created today.

// requires .NET 4

public static TReturn NullOr<TIn, TReturn>(this TIn obj, Func<TIn, TReturn> func,
        TReturn elseValue = default(TReturn)) where TIn : class
    { return obj != null ? func(obj) : elseValue; }

// versions for CLR 2, which doesn't support optional params

public static TReturn NullOr<TIn, TReturn>(this TIn obj, Func<TIn, TReturn> func,
        TReturn elseValue) where TIn : class
    { return obj != null ? func(obj) : elseValue; }
public static TReturn NullOr<TIn, TReturn>(this TIn obj, Func<TIn, TReturn> func)
        where TIn : class
    { return obj != null ? func(obj) : default(TReturn); }

It lets you do this:

var lname = thingy.NullOr(t => t.Name).NullOr(n => n.ToLower());

which is more fluent and (IMO) easier to read than this:

var lname = (thingy != null ? thingy.Name : null) != null
    ? thingy.Name.ToLower() : null;

8 Comments

What if I want thingy.NullOr(t => t.Count), where Count is an int ? You should return default(TReturn) rather than null, that way you won't need the class constraint and it will work for value types too
TIn should be required to be a class, otherwise this entire extension method makes no sense (value types cannot be null). And your example with t.Count does work with the above extension method. Could you take a second look?
@Scott: this is a useful method to a common problem. However, I believe TReturn elseValue = default(TReturn) is only available to .NET 4.0? I have 3.5 SP1 and I've never seen that construct (neither has my compiler). I just moved this to inside the method. One issue, however, is that boxing a nullable type to object for use with the method yields an unexpected result (0 vs expected null).
@Jim: the default(T) keyword has been there since VS2005, but I think default parameters is a new .NET 4 feature. The easy way around it should be to have two variants, one that takes the param and one that does not. I'll update the answer to be CLR 2.0 compatible. Regarding the boxing - that's the point of default. It will be 0-initialized data for a value type, and null for all reference types. A TReturn of a value type should remain unboxed all the way through the function.
@Scott: My question was about the default parameter, which I've only seen in dynamic languages like Ruby. My point regarding nullable types is that returning x.Value should return null (if, for example, int? was null) or the value if int? has a value. Returning 0 when int? x = null is passed and boxed to object is an odd case. I've seen similar checks for nullable types in libraries such as fluent nhibernate and linfu (I think) for this specific case, allowing you to drop the class constraint as previously suggested.
|
14
votes

"Please mark your answers with an acceptance to put the code in the Codeplex project."

Why? All the Stuff on this site under CC-by-sa-2.5, so just put your Extension overflow Project under the same license and you can freely use it.

Anyway, here is a String.Reverse function, based on this question.

/// <summary>
/// Reverse a String
/// </summary>
/// <param name="input">The string to Reverse</param>
/// <returns>The reversed String</returns>
public static string Reverse(this string input)
{
    char[] array = input.ToCharArray();
    Array.Reverse(array);
    return new string(array);
}

6 Comments

Doesn't String already implement IEnumerable<char>? So you'd just need to do return new String(input.Reverse());
An implementation using StringBuilder should be faster.
@CodeInChaos The Benchmarking in stackoverflow.com/questions/228038 measured that StringBuilder is slower.
You're right. It seems like the thread safety requirements (probably to ensure immutability of the string returned by ToString) slow StringBuilder down a lot.
Hope you don't encounter any surrogates or combining characters.
|
14
votes

I got tired of tedious null-checking while pulling values from MySqlDataReader, so:

public static DateTime? GetNullableDateTime(this MySqlDataReader dr, string fieldName)
{
    DateTime? nullDate = null;
    return dr.IsDBNull(dr.GetOrdinal(fieldName)) ? nullDate : dr.GetDateTime(fieldName);
}

public static string GetNullableString(this MySqlDataReader dr, string fieldName)
{
    return dr.IsDBNull(dr.GetOrdinal(fieldName)) ? String.Empty : dr.GetString(fieldName);
}

public static char? GetNullableChar(this MySqlDataReader dr, string fieldName)
{
    char? nullChar = null;
    return dr.IsDBNull(dr.GetOrdinal(fieldName)) ? nullChar : dr.GetChar(fieldName);
}

Of course this could be used with any SqlDataReader.


Both hangy and Joe had some good comments on how to do this, and I have since had an opportunity to implement something similar in a different context, so here is another version:

public static int? GetNullableInt32(this IDataRecord dr, int ordinal)
{
    int? nullInt = null;
    return dr.IsDBNull(ordinal) ? nullInt : dr.GetInt32(ordinal);
}

public static int? GetNullableInt32(this IDataRecord dr, string fieldname)
{
    int ordinal = dr.GetOrdinal(fieldname);
    return dr.GetNullableInt32(ordinal);
}

public static bool? GetNullableBoolean(this IDataRecord dr, int ordinal)
{
    bool? nullBool = null;
    return dr.IsDBNull(ordinal) ? nullBool : dr.GetBoolean(ordinal);
}

public static bool? GetNullableBoolean(this IDataRecord dr, string fieldname)
{
    int ordinal = dr.GetOrdinal(fieldname);
    return dr.GetNullableBoolean(ordinal);
}

9 Comments

This should also work as an extension method for IDataReader.
Actually, make the "this" parameter of type IDataRecord for maximum compatibility. In my version of this, I have an overload that takes an ordinal, which the fieldName version calls. Saves the "GetOrdinal" followed by a lookup by name.
There is a proper implementation, that can deal with any value type: rabdullin.com/journal/2008/12/6/…
Thanks Rinat, I have actually got this down to a single generic method - see stackoverflow.com/questions/303287
All of these methods appear to be un-needed as you can use the as keyword to get a value from a reader allowing for null. If you combine the null coalescing ?? operator with the as operator you can even have a non-null default value for going directly to a value type. See stackoverflow.com/questions/746767/…
|
14
votes

It irritated me that LINQ gives me an OrderBy that takes a class implementing IComparer as an argument, but does not support passing in a simple anonymous comparer function. I rectified that.

This class creates an IComparer from your comparer function...

/// <summary>
///     Creates an <see cref="IComparer{T}"/> instance for the given
///     delegate function.
/// </summary>
internal class ComparerFactory<T> : IComparer<T>
{
    public static IComparer<T> Create(Func<T, T, int> comparison)
    {
        return new ComparerFactory<T>(comparison);
    }

    private readonly Func<T, T, int> _comparison;

    private ComparerFactory(Func<T, T, int> comparison)
    {
        _comparison = comparison;
    }

    #region IComparer<T> Members

    public int Compare(T x, T y)
    {
        return _comparison(x, y);
    }

    #endregion
}

...and these extension methods expose my new OrderBy overloads on enumerables. I doubt this works for LINQ to SQL, but it's great for LINQ to Objects.

public static class EnumerableExtensions
{
    /// <summary>
    /// Sorts the elements of a sequence in ascending order by using a specified comparison delegate.
    /// </summary>
    public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector,
                                                                     Func<TKey, TKey, int> comparison)
    {
        var comparer = ComparerFactory<TKey>.Create(comparison);
        return source.OrderBy(keySelector, comparer);
    }

    /// <summary>
    /// Sorts the elements of a sequence in descending order by using a specified comparison delegate.
    /// </summary>
    public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector,
                                                                               Func<TKey, TKey, int> comparison)
    {
        var comparer = ComparerFactory<TKey>.Create(comparison);
        return source.OrderByDescending(keySelector, comparer);
    }
}

You're welcome to put this on codeplex if you like.

Comments

13
votes

This one is for MVC it adds the ability to generate a <label /> tag to the Html variable that is available in every ViewPage. Hopefully it will be of use to others trying to develop similar extensions.

Use:

<%= Html.Label("LabelId", "ForId", "Text")%>

Output:

<label id="LabelId" for="ForId">Text</label>

Code:

public static class HtmlHelperExtensions
{
    public static string Label(this HtmlHelper Html, string @for, string text)
    {
        return Html.Label(null, @for, text);
    }

    public static string Label(this HtmlHelper Html, string @for, string text, object htmlAttributes)
    {
        return Html.Label(null, @for, text, htmlAttributes);
    }

    public static string Label(this HtmlHelper Html, string @for, string text, IDictionary<string, object> htmlAttributes)
    {
        return Html.Label(null, @for, text, htmlAttributes);
    }

    public static string Label(this HtmlHelper Html, string id, string @for, string text)
    {
        return Html.Label(id, @for, text, null);
    }

    public static string Label(this HtmlHelper Html, string id, string @for, string text, object htmlAttributes)
    {
        return Html.Label(id, @for, text, new RouteValueDictionary(htmlAttributes));
    }

    public static string Label(this HtmlHelper Html, string id, string @for, string text, IDictionary<string, object> htmlAttributes)
    {
        TagBuilder tag = new TagBuilder("label");

        tag.MergeAttributes(htmlAttributes);

        if (!string.IsNullOrEmpty(id))
            tag.MergeAttribute("id", Html.AttributeEncode(id));

        tag.MergeAttribute("for", Html.AttributeEncode(@for));

        tag.SetInnerText(Html.Encode(text));

        return tag.ToString(TagRenderMode.Normal);
    }
}

2 Comments

Check out MvcContrib.FluentHtml
This probably should be duplicated with Literal instead.
12
votes

Turn this:

DbCommand command = connection.CreateCommand();
command.CommandText = "SELECT @param";

DbParameter param = command.CreateParameter();
param.ParameterName = "@param";
param.Value = "Hello World";

command.Parameters.Add(param);

... into this:

DbCommand command = connection.CreateCommand("SELECT {0}", "Hello World");

... using this extension method:

using System;
using System.Data.Common;
using System.Globalization;
using System.Reflection;

namespace DbExtensions {

   public static class Db {

      static readonly Func<DbConnection, DbProviderFactory> getDbProviderFactory;
      static readonly Func<DbCommandBuilder, int, string> getParameterName;
      static readonly Func<DbCommandBuilder, int, string> getParameterPlaceholder;

      static Db() {

         getDbProviderFactory = (Func<DbConnection, DbProviderFactory>)Delegate.CreateDelegate(typeof(Func<DbConnection, DbProviderFactory>), typeof(DbConnection).GetProperty("DbProviderFactory", BindingFlags.Instance | BindingFlags.NonPublic).GetGetMethod(true));
         getParameterName = (Func<DbCommandBuilder, int, string>)Delegate.CreateDelegate(typeof(Func<DbCommandBuilder, int, string>), typeof(DbCommandBuilder).GetMethod("GetParameterName", BindingFlags.Instance | BindingFlags.NonPublic, Type.DefaultBinder, new Type[] { typeof(Int32) }, null));
         getParameterPlaceholder = (Func<DbCommandBuilder, int, string>)Delegate.CreateDelegate(typeof(Func<DbCommandBuilder, int, string>), typeof(DbCommandBuilder).GetMethod("GetParameterPlaceholder", BindingFlags.Instance | BindingFlags.NonPublic, Type.DefaultBinder, new Type[] { typeof(Int32) }, null));
      }

      public static DbProviderFactory GetProviderFactory(this DbConnection connection) {
         return getDbProviderFactory(connection);
      }

      public static DbCommand CreateCommand(this DbConnection connection, string commandText, params object[] parameters) {

         if (connection == null) throw new ArgumentNullException("connection");

         return CreateCommandImpl(GetProviderFactory(connection).CreateCommandBuilder(), connection.CreateCommand(), commandText, parameters);
      }

      private static DbCommand CreateCommandImpl(DbCommandBuilder commandBuilder, DbCommand command, string commandText, params object[] parameters) {

         if (commandBuilder == null) throw new ArgumentNullException("commandBuilder");
         if (command == null) throw new ArgumentNullException("command");
         if (commandText == null) throw new ArgumentNullException("commandText");

         if (parameters == null || parameters.Length == 0) {
            command.CommandText = commandText;
            return command;
         }

         object[] paramPlaceholders = new object[parameters.Length];

         for (int i = 0; i < paramPlaceholders.Length; i++) {

            DbParameter dbParam = command.CreateParameter();
            dbParam.ParameterName = getParameterName(commandBuilder, i);
            dbParam.Value = parameters[i] ?? DBNull.Value;
            command.Parameters.Add(dbParam);

            paramPlaceholders[i] = getParameterPlaceholder(commandBuilder, i);
         }

         command.CommandText = String.Format(CultureInfo.InvariantCulture, commandText, paramPlaceholders);

         return command;
      }
   }
}

More ADO.NET extension methods: DbExtensions

Comments

1
2 3 4 5

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.