Cool stuff in FubuCore No. 2: Extension Methods

This is the second post of the FubuCore series mentioned in the Introduction post.

This post covers the various and plentiful extension methods contained in the FubuCore project. We have built up these extensions methods over the last 3-4 years in anger. Some of them may be a little sloppy and not up to your liking or taste level, but all of them are used heavily and have been running in multiple production systems for quite a while (some of them over 2 years). We find most of them to be invaluable and use them every day. I hope you find some value in them as well.

IfNotNull

Various overloads (Source)

This one is super handy.  How many times have you written code like this?

if( value != null )
{
    doSomething();

}

 

Well, it really stinks when you’re in the middle of a code flow and you need to do something only if “value” is not null. Well, now you can do stuff like this:

var name = employee.IfNotNull(e => e.FullName);
// or
employee.IfNotNull(e => doSomething(e));

 

Hiding Data In Views With If/IfNot

(Source)

With Fubu authorization, you can hide pieces of information in the view if the current ser doesn’t have access to it.  We wrote short-hand methods to assist us with this in the view. Assume the view’s model has a property called “CanSeeSalaryInformation” which represents the result of an authorization check for a user permission.

<span><%= employee.Salary.If(()=> Model.CanSeeSalaryInformation)%></span>

 

Making Dictionary.Get Not As Annoying

Various overloads (Source)

If you do manage to find yourself using a Dictionary instead of a Cache, you can get around some of the pain of having to do the “ContainsKeys” checks by using the Get extension methods. A lot of times you want to get a value from a dictionary but don’t want to do all the “ContainsKey” checking or messing with the “out” variable in the “TryGetValue” method.

Let’s say you want to get the value of a key from a dictionary which may not be there. And if it’s not there, then return a default value (let’s say, empty string).

dictionary.Get("mykey", "");

Enumerable Extensions

(Source)

Like most programmers, we do a lot of stuff with enumerables (lists, arrays, and other fun list-y type structures). So we’ve evolved a lot of enhancements and extensions to make them easier to use in various situation.

IList<T> Extensions

Fill(T value): Add an item to a list if it isn’t already in the list.

RemoveAll(Func<T, bool> whereEvaluator): Removes items from the list that match the function/predicate.

AddRange(IEnumerable<T> items): For some reason, AddRange is only on List<T> and not on IList<T>, so we added it to IList<T>.

AddMany(params T[] items): Just like AddRange, but allows for many param arguments as well as method chaining.

IEnumerable<T> Extensions

Each(Action<T> action): Just like “foreach”, but is inline and allows method chaining.

FirstValue(Func<T, UReturn> returnFunc): Kinda like FirstOrDefault, but more like combining a Where and a Select and a FirstOrDefault in one method.  This method will iterate over the enumerable, executing your returnFunc until it gets a non-null result.  If none was found, it just returns null.

IsEqualTo(IEnumerable<T> expected): This one we use (almost?) exclusively for testing to ensure the result of some method returns exactly what we expected. It will check the lengths/count of each enumerable and then verify that each item in each list passes a call to “.Equals()”.

String Extensions

Join(string separator): Just like String.Join except it allows method chaining.

Stream Extensions

(Source)

ReadAllText: This does the tedium of new()’ing up a StreamReader and calling ReadToEnd.  It saves a few lines of code when all you want to do is open a stream and read the whole thing in. I think we use this for reading text embedded assembly resources  If you’re working with files, it’s better to just call File.ReadAllText.

String Extensions

(Source)

CombineToPath(string root): If the path is rooted, just returns the path.  Otherwise, this combines the root and path. (Uses Path.IsPathRooted and Path.Combine)

ToFullPath(): Just like Path.GetFullPath, but allows method chaining.

AppendPath(params string[] paths): Repeatedly calls Path.Combine on a list of paths (i.e. /bar/baz/zab/rab).

PathRelativeTo(string root): Makes the current string (assumed to be a path) rooted against the specified root. (i.e. “/bar/baz”.PathRelativeTo(“c:”) will result in “c:/bar/baz”).

IsEmpty(): Same as String.IsNullOrEmpty, but hangs off the string itself as an extension method.

IsNotEmpty(): Opposite of IsEmpty.

IsNotEmpty(Action<string> action): Same as IsNotEmpty() but will execute an action if the string is, in fact, not empty. This is useful for keeping statements in-line.

ToBool: Converts a string to boolean. It handles the null/empty check, and then calls Bool.Parse.

ToFormat: (My personal favorite) Calls String.Format, but allows for method chaining. Example:

return "You have {0} turns remaining.".ToFormat(numTurnsLeft);

EqualsIgnoreCase(string otherString): Calls String.Equals with StringComparison.InvariantCultureIgnoreCase.

Capitalize: A more convenient way to call: CultureInfo.CurrentCulture.TextInfo.ToTitleCase(value)

HtmlAttributeEncode, HtmlEncode, HtmlDecode, UrlEncode, UrlDecode: A more convenient way to call the corresponding methods on System.Web.HttpUtility.

ConvertCRLFToBreaks(string plainText): Converts “\r\n” or “\n” to “<br/>” (handy for html-izing some plain text”).

ToDateTime(string dateTimeValue): A more convenient way of calling DateTime.Parse.

ToGmtFormattedDate: Prints out a log-file friendly date/time stamp in full format in the GMT timezone (i.e. “yyyy-MM-dd hh:mm:ss tt GMT”).

ToDelimitedArray: A more convenient way of calling String.Split, plus it strips away extra whitespace so “a  “,”b”, and ”    c” get turned into “a,b,c”.

IsValidNumber: Uses regex to attempt to determine if the string contains something recognizable as a number. If memory serves, this was written in anger at Decimal.Parse which never seemed forgiving enough and would frequently miss values that were clearly (to humans) numbers.

getPathParts: Breaks down a string like “c:/bar/baz/zab” into a list of strings “c:”, “bar”, “baz”, and “zab”.

DirectoryPath: A more convenient way of calling Path.GetDirectoryName.

Type Extensions

(Source)

These are some *really* handy methods if you do a lot of work with generics, expression trees, or both.

Unfortunately, this blog post would be four times larger if I mentioned all the great extension methods.  I strongly suggest you browse through this source file (linked above) because you will definitely find at least one thing that you can use.

I hand-picked a few ones that I thought were especially useful and might whet your appetite :

IsNullableOfT(): Determines if the given type implements Nullable<> or not (i.e. DateTime?).

IsNullableOf(Type otherType): Determines if the given type is a Nullable<otherType> or not. For example, typeof(DateTime?).IsNullableOf(typeof(DateTime)) would be True.

IsTypeOrNullableOf<T>:  Useful for checking if this type is one of DateTime or a DateTime?, for example.

CanBeCastTo<T>: This helps to rectify the oft-confusing backward logic of Type.IsAssignableFrom.

IsConcreteWithDefaultCtor: Determines if this type is a concrete type with a default/open constructor (i.e. you could call Activator.CreateInstance() on it with no exceptions).

Related Articles:

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

About Chad Myers

Chad Myers is the Director of Development for Dovetail Software, in Austin, TX, where he leads a premiere software team building complex enterprise software products. Chad is a .NET software developer specializing in enterprise software designs and architectures. He has over 12 years of software development experience and a proven track record of Agile, test-driven project leadership using both Microsoft and open source tools. He is a community leader who speaks at the Austin .NET User's Group, the ADNUG Code Camp, and participates in various development communities and open source projects.
This entry was posted in .NET, cool-stuff-in-fubu, fubucore, FubuMVC. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://mutedsolutions.com Derick Bailey

    this looks like it would be a good candidate for pulling out into a separate nuget package, like the html tags. there’s a lot of great stuff in here that could benefit people outside of fubu, easily.

    • Anonymous

      @derickbailey:disqus This has its own repo on github and we’ve got the wirings for nuget. Don’t know the timing on it but the intention is make sure it’s FubuMVC-agnostic

    • http://chadmyers.lostechies.com Chad Myers

      We already did it (a week or two ago). http://www.nuget.org/List/Packages/FubuCore

      We broke out FubuCore a month or two ago, but only recently was it made into a Nuget package and published.  The StoryTeller project uses FubuCore.  Jeremy was considering using it in StructureMap, but there are some issues that may prevent him (such as size bloat for Silverlight deployment, etc)

  • Pingback: The Morning Brew - Chris Alcock » The Morning Brew #863

  • Ramon Smits

    a lot of that stuff already exists in http://umbrella.codeplex.com/ . This code would extend that codebase very well.

  • Eric

    Awesome Chad, these look very handy to have in one consolidated lib.