5 More C# Extension Methods for the Stocking! (plus a bonus method for enums)
To continue from my previous collection of extension methods, I thought I would add five more extension methods to the list.
<sung to the tune of 12 days of Christmas>
On the 15th day of C# Advent, I gave to my read-ers...fiiiiive Extension Methods.
Sorry, I couldn't help it.
In spirit with the C# Advent calendar and since my 10 Extremely Useful .NET Extension Methods post was a big hit, why not add some more extension methods as a C# post? You can never have enough extension methods.
Also, while these extensions are small, they've been in production for a long time.
ToInt()
Of course, we always have the familiar .ToString()
, but what happens when we want to convert a simple string to an integer?
You have to set up an if..statement, look for a character...it just takes too much. So why not just make it an extension method and be done with it?
// Usage: var count = strCount.ToInt(); public static int ToInt(this String input) { int result; if (!int.TryParse(input, out result)) { result = 0; } return result; }
If it can't convert it, it will return zero. If it can convert it, result will contain the value.
Of course, you can modify to return a -1 if you want.
OrdinalSuffix()
Since I've built my blog, I wanted to have my dates dressed up a little bit.
You know...have an 'rd' added to the end of a 3 so you have the "3rd."
This extension method places a 'th', 'st', 'nd', 'rd', or 'th' to the end of the number.
// Usage: var day = DateTime.Now.OrdinalSuffix(); // Returns 13th public static string OrdinalSuffix(this DateTime datetime) { int day = datetime.Day;
if (day % 100 >= 11 && day % 100 <= 13) return String.Concat(day, "th");
switch (day % 10) { case 1: return String.Concat(day, "st"); case 2: return String.Concat(day, "nd"); case 3: return String.Concat(day, "rd"); default: return String.Concat(day, "th"); } }
Simple usage and has been working for 6 years.
Occurrence()
This one is by far the smallest and most helpful one around.
This just counts the number of occurrences in a string.
// Usage: var count = "supercalifragilisticexpealidocious".Occurrence("li"); // returns 3 public static int Occurrence(this String instr, string search) { return Regex.Matches(instr, search).Count; }
Using a quick and dirty regular expression gets the job done.
Heck, you could even use that instead of the extension method...it's a one-liner. <shrug>
Join<T>()/Join()
Joining strings together can be a pain, but luckily, there is the string.Join(). We can use it to simplify the Join method for IEnumerables and Arrays.
public static string Join<T>(this IEnumerable<T> self, string separator) { return String.Join(separator, self.Select(e => e.ToString()).ToArray()); }
public static string Join(this Array array, string separator) { return String.Join(separator, array); }
With these two extension methods, you can take an array or List<string>() and make a comma-delimited list in no time or build a broken-up URL with dashes as the URL name.
ToQueryString()
Have you ever wanted to take a NameValueCollection and convert it into a query string for a URL?
You're in luck.
// Usage: var qs = collection.ToQueryString(); // returns name=bob&age=15&location=Columbus public static string ToQueryString(this NameValueCollection nvc) { return string.Join("&", nvc.AllKeys.Select( key => string.Format("{0}={1}", HttpUtility.UrlEncode(key), HttpUtility.UrlEncode(nvc[key])))); }
Enums.ToList<T>() - Bonus Method
I'm slowly moving away from enumerated types, but until I can completely remove them from my vocabulary, I sometimes have a need to display enumerated types into a dropdownlist.
So how do you take this:
public enum Frequency { None = 0, Seconds = 1, Minutes = 2, Hours = 3, Days = 4, Weeks = 5, Months = 6, Years = 7 }
And turn it into a dropdownlist?
First, you need a Description Attribute and apply it to each Enum item.
public enum Frequency { [Description("None")]
None = 0, [Description("Seconds")]
Seconds = 1, .
.
}
This Enums.ToList<T> static method is meant to take enumerations with description attributes and convert them into a NameValueCollection for possibly a dropdown.
Once you have the NameValueCollection, you can use another extension method I've mentioned before for converting an Enumerable list into an ASP.NET MVC SelectListItem for a dropdown.
/// <summary> /// Example: Enums.ToList<MyEnum>(); /// </summary> public static class Enums { public static NameValueCollection ToList<T>() where T : struct { var result = new NameValueCollection();
if (!typeof(T).IsEnum) return result;
var enumType = typeof(T); var values = Enum.GetValues(enumType); foreach (var value in values) { var memInfo = enumType.GetMember(enumType.GetEnumName(value)); var descriptionAttributes = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false); var description = descriptionAttributes.Length > 0 ? ((DescriptionAttribute)descriptionAttributes.First()).Description : value.ToString(); result.Add(description, value.ToString()); }
return result; } }
It's a quick way to write code without writing a ton of code. It also gives a clear understanding of what the code does through the name.
Conclusion
While all of these extension methods may be small, they're meant to accomplish three things:
- Create a "sentence" for developers so they don't lose their stride just like novel writers. The statements must flow.
- Get out of a programmer's way by passing in minimal parameters.
- Make a complicated piece of code into something extremely easy to use with extension methods (when was the last time you used the LINQ Aggregate or Group without looking up the syntax?) ;-)
Extension methods provide an impressive way to take not just your classes, but even the .NET Framework classes, to new heights and extending the language even further for ease of use.
Microsoft also uses extension methods in ASP.NET Core 1.0 and 2.0 for their Middleware, meaning you can build your own pipeline using custom Middleware components. Absolutely awesome!
Finally, I want to thank Matt Groves for the opportunity to "play in the reindeer games" for the C# advent calendar. :-)
Next year, I encourage other developers to write a quick post about C#. This is a great stepping stone for beginning writers. Give it a shot!
Do you have some favorite extensions? Do they simplify syntax or does it just read better? Post your comments below and let's discuss.