Almost always, the first extensions methods I add to a system are these:
public static class EnumerableExtensions { public static string JoinToString<T>(this IEnumerable<T> enumerable, Func<T, object> selector, string separator) { return enumerable.Select(selector).JoinToString(separator); } public static string JoinToString<T>(this IEnumerable<T> enumerable, Func<T, object> selector) { return enumerable.Select(selector).JoinToString(", "); } public static string JoinToString(this IEnumerable enumerable, string separator) { var strings = enumerable.Cast<object>() .Select(e => e == null ? "(null)" : e.ToString()) .ToArray(); return string.Join(separator, strings); } } |
which allows me to format any sequence of stuff sensibly, easily, and inline, e.g. like so:
Log.WarnFormat("Some stuff happened to stuff with these names: {0}", names.JoinToString(", ")); |
and so:
Log.WarnFormat("Some stuff happened to things with these names: {0}", things.JoinToString(t => t.Name)); |
and so:
catch(ReflectionTypeLoadException exception) { Log.ErrorFormat(@"ZOMG!!111something happened!! {0}", exception.LoaderExceptions.JoinToString(Environment.NewLine)); } |
Nifty!