Let's make a list of answers where you post your excellent and favorite extension methods [1].
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 [2].
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 [3] and Unit Tested [4].
11.11.2008 There is still room for more developers. ;-) Join NOW!
11.11.2008 Third contributer joined ExtensionOverflow [5], welcome to BKristensen [6]
11.11.2008 FormatWith is now Implemented [7] and Unit Tested [8].
09.11.2008 Second contributer joined ExtensionOverflow [9]. welcome to chakrit [10].
09.11.2008 We need more developers. ;-)
09.11.2008 ThrowIfArgumentIsNull in now Implemented [11] and Unit Tested [12] on Codeplex.
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....
}
In
, but maybe IsIn
would be better. - Winston Smith
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. - JBSnorro
I have various extension methods in my MiscUtil [1] 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 [2] 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.
[1] http://pobox.com/~skeet/csharp/miscutil19.June(1976)
is fine (testing at least) but I don't like 30.Minutes()
. Why not use operator overloading to reach something more equivalent to scientific notations like 30 * min
or 30 * Minutes
if you like. - Lasse Espeholt
min
and Minutes
defined somewhere in each source file that uses them... and that could get annoying. With the extension method it's just a case of adding the using
directive (which we don't tend to look at anyway). But it's definitely a matter of taste. - Jon Skeet
30 * SI.min
but that just make it less clear. - Lasse Espeholt
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 [1].
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");
..
[1] http://pastebin.com/f3e2a94d6Are 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!");
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. - Dan Tao
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. - Lasse Espeholt
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))
{
// ....
}
<
) seemed "unnatural" to me, at first, too -- writing public static class ComparableExtensions {
before my code doesn't exactly seem intuitive. - Ken
enum
(neither
, lower
, upper
, both
) as a third parameter to specifiy equality on bounds. default to neither
. - zzzzBov
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);
var list = new List<int>{5,4,8,4,2};
- Arnis Lapsa
ICollection<T>
; then it could also be used on, for example, LinkedList<T>
and HashSet<T>
, not just indexed collections. - Dan Tao
AppendRange()
- it makes the difference between this and a collection initializer more obvious. - Joel Coehoorn
list.AddRange(values);
? - stevehipwell
items = items.Concat(new[] {5, 4, 8, 4, 2})
. It works with any IEnumerable (for both the subject and the argument), and if you really want to end up with a list, just call ToList()
when you're done. - StriplingWarrior
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.
}
}
ToXml()
(like ToString()
) - Jay Bazuzi
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
My conversion extensions which allow you to do:
int i = myString.To<int>();
Here it is, as posted on TheSoftwareJedi.com [1]
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.
[1] http://thesoftwarejedi.blogspot.com/2008/05/extension-methods.htmlToOrNull
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? - Dan Tao
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 :-)]
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 [1]
--- 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:
[1] http://geekswithblogs.net/sdorman/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.
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.
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();
[1] http://www.codeplex.com/DateTimeExtensionsgitorious.org/cadenza [1] is a full library of some of the most useful extension methods I've seen.
[1] http://www.gitorious.org/cadenzaHere 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());
}
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();
}
}
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
};
}
}
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...
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 [1] project.
[1] http://www.codeplex.com/extensionmethoddefault(T)
for this and remove the class requirement. - Joel Coehoorn
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. - StriplingWarrior
I miss the Visual Basic's With statement [1] 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
[1] http://msdn.microsoft.com/en-us/library/wc500chb(VS.80).aspx{ var x = someVeryVeryLonggggVariableName; /* do something with x */ }
? - Heinzi
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
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(....)
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
Below is an extension method [1] that adapts Rick Strahl's code [2] (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();
}
}
}
}
[1] http://www.shrinkrays.net/code-snippets/csharp/an-extension-method-for-converting-a-byte-array-to-a-string.aspxHere'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;
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 - Thomas Levesque
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 Schubert
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. - scobi
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. - Jim Schubert
int?
, the class constraint is required or the function won't compile. You cannot compare to null
without requiring a reference type. Now, it is possible to have a second version of the function that takes TIn?
But what should it do? Return a null or the boxed Value
? But we already have that in the form of the nullable.. I don't see the added value... - scobi
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);
}
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/… - stevehipwell
as
in this way. Did you test this? DBNull values will throw an exception. - Adam Lassek
"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 [1], 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 [2].
/// <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);
}
[1] http://creativecommons.org/licenses/by-sa/2.5/"\r\n"
. Or double newlines of the form "\n\r"
, for that matter. - leviathanbadger
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.
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);
}
}
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 [1]
[1] http://dbextensions.sourceforge.net/One of my favorites is an IsLike() extension on String. IsLike() matches VB's Like operator [1], and is handy when you don't want to write a full-on regex to solve your problem. Usage would be something like this:
"abc".IsLike("a*"); // true
"Abc".IsLike("[A-Z][a-z][a-z]"); // true
"abc123".IsLike("*###"); // true
"hat".IsLike("?at"); // true
"joe".IsLike("[!aeiou]*"); // true
"joe".IsLike("?at"); // false
"joe".IsLike("[A-Z][a-z][a-z]"); // false
Here's the code
public static class StringEntentions {
/// <summary>
/// Indicates whether the current string matches the supplied wildcard pattern. Behaves the same
/// as VB's "Like" Operator.
/// </summary>
/// <param name="s">The string instance where the extension method is called</param>
/// <param name="wildcardPattern">The wildcard pattern to match. Syntax matches VB's Like operator.</param>
/// <returns>true if the string matches the supplied pattern, false otherwise.</returns>
/// <remarks>See http://msdn.microsoft.com/en-us/library/swf8kaxw(v=VS.100).aspx</remarks>
public static bool IsLike(this string s, string wildcardPattern) {
if (s == null || String.IsNullOrEmpty(wildcardPattern)) return false;
// turn into regex pattern, and match the whole string with ^$
var regexPattern = "^" + Regex.Escape(wildcardPattern) + "$";
// add support for ?, #, *, [], and [!]
regexPattern = regexPattern.Replace(@"\[!", "[^")
.Replace(@"\[", "[")
.Replace(@"\]", "]")
.Replace(@"\?", ".")
.Replace(@"\*", ".*")
.Replace(@"\#", @"\d");
var result = false;
try {
result = Regex.IsMatch(s, regexPattern);
}
catch (ArgumentException ex) {
throw new ArgumentException(String.Format("Invalid pattern: {0}", wildcardPattern), ex);
}
return result;
}
}
[1] http://msdn.microsoft.com/en-us/library/swf8kaxw(v=VS.100).aspxSimilar to the string As and Is above, but global to all objects.
It's quite simple, but I use these a lot to alleviate parens explosion with boxing.
public static class ExtensionMethods_Object
{
[DebuggerStepThrough()]
public static bool Is<T>(this object item) where T : class
{
return item is T;
}
[DebuggerStepThrough()]
public static bool IsNot<T>(this object item) where T : class
{
return !(item.Is<T>());
}
[DebuggerStepThrough()]
public static T As<T>(this object item) where T : class
{
return item as T;
}
}
I am happy for this code to be used at codeplex, indeed it already is.
To<T>
to the list that does (T)item
. - scobi
Another useful one for me:
/// <summary>
/// Converts any type in to an Int32
/// </summary>
/// <typeparam name="T">Any Object</typeparam>
/// <param name="value">Value to convert</param>
/// <returns>The integer, 0 if unsuccessful</returns>
public static int ToInt32<T>(this T value)
{
int result;
if (int.TryParse(value.ToString(), out result))
{
return result;
}
return 0;
}
/// <summary>
/// Converts any type in to an Int32 but if null then returns the default
/// </summary>
/// <param name="value">Value to convert</param>
/// <typeparam name="T">Any Object</typeparam>
/// <param name="defaultValue">Default to use</param>
/// <returns>The defaultValue if unsuccessful</returns>
public static int ToInt32<T>(this T value, int defaultValue)
{
int result;
if (int.TryParse(value.ToString(), out result))
{
return result;
}
return defaultValue;
}
Example:
int number = "123".ToInt32();
or:
int badNumber = "a".ToInt32(100); // Returns 100 since a is nan
IEnumerable<>
ShuffleI used the Fisher-Yates [1] the algorithm to implement a shuffle function.
By using yield return
and breaking the code in two functions, it achieves proper argument validation and deferred execution. (thanks,
Dan
[2], for pointing this flaw in my first version)
static public IEnumerable<T> Shuffle<T>(this IEnumerable<T> source)
{
if (source == null) throw new ArgumentNullException("source");
return ShuffleIterator(source);
}
static private IEnumerable<T> ShuffleIterator<T>(this IEnumerable<T> source)
{
T[] array = source.ToArray();
Random rnd = new Random();
for (int n = array.Length; n > 1;)
{
int k = rnd.Next(n--); // 0 <= k < n
//Swap items
if (n != k)
{
T tmp = array[k];
array[k] = array[n];
array[n] = tmp;
}
}
foreach (var item in array) yield return item;
}
[1] http://en.wikipedia.org/wiki/Fisher-Yates_shuffleShuffledEnumerable
class that only does this work (and probably caches it) on GetEnumerator
to provide lazy evaluation a.k.a. deferred execution. Otherwise if someone calls, e.g., var shuffledNames = myObjects.Select(x => x.Name).Distinct().Shuffle();
the operation will get executed immediately, which may not be what he/she expects. Good answer, though! - Dan Tao
yield return
solves the problem. I'll edit my answer. - jpbochi
OrderBy
. Nicely done! - Dan Tao
foreach
loop and replace the body of the if
statement with yield return array[k] = array[n];
- leviathanbadger
There's a lot of functionality you can get from the Random
class.
Below are some extension methods I use from time to time. With these, in addition to Next
and NextDouble
, the Random
class gives you NextBool
, NextChar
, NextDateTime
, NextTimeSpan
, NextDouble
(accepting minValue
and maxValue
parameters), and my personal favorite: NextString
. There are more (NextByte
, NextShort
, NextLong
, etc.); but those are mostly for completeness and don't get used as much. So I didn't include them here (this code is long enough as it is!).
// todo: implement additional CharType values (e.g., AsciiAny)
public enum CharType {
AlphabeticLower,
AlphabeticUpper,
AlphabeticAny,
AlphanumericLower,
AlphanumericUpper,
AlphanumericAny,
Numeric
}
public static class RandomExtensions {
// 10 digits vs. 52 alphabetic characters (upper & lower);
// probability of being numeric: 10 / 62 = 0.1612903225806452
private const double AlphanumericProbabilityNumericAny = 10.0 / 62.0;
// 10 digits vs. 26 alphabetic characters (upper OR lower);
// probability of being numeric: 10 / 36 = 0.2777777777777778
private const double AlphanumericProbabilityNumericCased = 10.0 / 36.0;
public static bool NextBool(this Random random, double probability) {
return random.NextDouble() <= probability;
}
public static bool NextBool(this Random random) {
return random.NextDouble() <= 0.5;
}
public static char NextChar(this Random random, CharType mode) {
switch (mode) {
case CharType.AlphabeticAny:
return random.NextAlphabeticChar();
case CharType.AlphabeticLower:
return random.NextAlphabeticChar(false);
case CharType.AlphabeticUpper:
return random.NextAlphabeticChar(true);
case CharType.AlphanumericAny:
return random.NextAlphanumericChar();
case CharType.AlphanumericLower:
return random.NextAlphanumericChar(false);
case CharType.AlphanumericUpper:
return random.NextAlphanumericChar(true);
case CharType.Numeric:
return random.NextNumericChar();
default:
return random.NextAlphanumericChar();
}
}
public static char NextChar(this Random random) {
return random.NextChar(CharType.AlphanumericAny);
}
private static char NextAlphanumericChar(this Random random, bool uppercase) {
bool numeric = random.NextBool(AlphanumericProbabilityNumericCased);
if (numeric)
return random.NextNumericChar();
else
return random.NextAlphabeticChar(uppercase);
}
private static char NextAlphanumericChar(this Random random) {
bool numeric = random.NextBool(AlphanumericProbabilityNumericAny);
if (numeric)
return random.NextNumericChar();
else
return random.NextAlphabeticChar(random.NextBool());
}
private static char NextAlphabeticChar(this Random random, bool uppercase) {
if (uppercase)
return (char)random.Next(65, 91);
else
return (char)random.Next(97, 123);
}
private static char NextAlphabeticChar(this Random random) {
return random.NextAlphabeticChar(random.NextBool());
}
private static char NextNumericChar(this Random random) {
return (char)random.Next(48, 58);
}
public static DateTime NextDateTime(this Random random, DateTime minValue, DateTime maxValue) {
return DateTime.FromOADate(
random.NextDouble(minValue.ToOADate(), maxValue.ToOADate())
);
}
public static DateTime NextDateTime(this Random random) {
return random.NextDateTime(DateTime.MinValue, DateTime.MaxValue);
}
public static double NextDouble(this Random random, double minValue, double maxValue) {
if (maxValue < minValue)
throw new ArgumentException("Minimum value must be less than maximum value.");
double difference = maxValue - minValue;
if (!double.IsInfinity(difference))
return minValue + (random.NextDouble() * difference);
else {
// to avoid evaluating to Double.Infinity, we split the range into two halves:
double halfDifference = (maxValue * 0.5) - (minValue * 0.5);
// 50/50 chance of returning a value from the first or second half of the range
if (random.NextBool())
return minValue + (random.NextDouble() * halfDifference);
else
return (minValue + halfDifference) + (random.NextDouble() * halfDifference);
}
}
public static string NextString(this Random random, int numChars, CharType mode) {
char[] chars = new char[numChars];
for (int i = 0; i < numChars; ++i)
chars[i] = random.NextChar(mode);
return new string(chars);
}
public static string NextString(this Random random, int numChars) {
return random.NextString(numChars, CharType.AlphanumericAny);
}
public static TimeSpan NextTimeSpan(this Random random, TimeSpan minValue, TimeSpan maxValue) {
return TimeSpan.FromMilliseconds(
random.NextDouble(minValue.TotalMilliseconds, maxValue.TotalMilliseconds)
);
}
public static TimeSpan NextTimeSpan(this Random random) {
return random.NextTimeSpan(TimeSpan.MinValue, TimeSpan.MaxValue);
}
}
I'm disappointed that the .NET Framework prefers that files and directories be represented as strings rather than objects, and that the FileInfo and DirectoryInfo types aren't as powerful as I'd wish. So, I started to write fluent extension methods as I needed them, e.g.:
public static FileInfo SetExtension(this FileInfo fileInfo, string extension)
{
return new FileInfo(Path.ChangeExtension(fileInfo.FullName, extension));
}
public static FileInfo SetDirectory(this FileInfo fileInfo, string directory)
{
return new FileInfo(Path.Combine(directory, fileInfo.Name));
}
Yes, you can put this in the codeplex
Some of my best method extensions (I have a lot!):
public static T ToEnum<T>(this string str) where T : struct
{
return (T)Enum.Parse(typeof(T), str);
}
//DayOfWeek sunday = "Sunday".ToEnum<DayOfWeek>();
public static string ToString<T>(this IEnumerable<T> collection, string separator)
{
return ToString(collection, t => t.ToString(), separator);
}
public static string ToString<T>(this IEnumerable<T> collection, Func<T, string> stringElement, string separator)
{
StringBuilder sb = new StringBuilder();
foreach (var item in collection)
{
sb.Append(stringElement(item));
sb.Append(separator);
}
return sb.ToString(0, Math.Max(0, sb.Length - separator.Length)); // quita el ultimo separador
}
//new []{1,2,3}.ToString(i=>i*2, ", ") --> "2, 4, 6"
Also, the next ones are meant to be able to continue in the same line in almost any situation, not declaring new variables and then removing state:
public static R Map<T, R>(this T t, Func<T, R> func)
{
return func(t);
}
ExpensiveFindWally().Map(wally=>wally.FirstName + " " + wally.LastName)
public static R TryCC<T, R>(this T t, Func<T, R> func)
where T : class
where R : class
{
if (t == null) return null;
return func(t);
}
public static R? TryCS<T, R>(this T t, Func<T, R> func)
where T : class
where R : struct
{
if (t == null) return null;
return func(t);
}
public static R? TryCS<T, R>(this T t, Func<T, R?> func)
where T : class
where R : struct
{
if (t == null) return null;
return func(t);
}
public static R TrySC<T, R>(this T? t, Func<T, R> func)
where T : struct
where R : class
{
if (t == null) return null;
return func(t.Value);
}
public static R? TrySS<T, R>(this T? t, Func<T, R> func)
where T : struct
where R : struct
{
if (t == null) return null;
return func(t.Value);
}
public static R? TrySS<T, R>(this T? t, Func<T, R?> func)
where T : struct
where R : struct
{
if (t == null) return null;
return func(t.Value);
}
//int? bossNameLength = Departament.Boss.TryCC(b=>b.Name).TryCS(s=>s.Length);
public static T ThrowIfNullS<T>(this T? t, string mensaje)
where T : struct
{
if (t == null)
throw new NullReferenceException(mensaje);
return t.Value;
}
public static T ThrowIfNullC<T>(this T t, string mensaje)
where T : class
{
if (t == null)
throw new NullReferenceException(mensaje);
return t;
}
public static T Do<T>(this T t, Action<T> action)
{
action(t);
return t;
}
//Button b = new Button{Content = "Click"}.Do(b=>Canvas.SetColumn(b,2));
public static T TryDo<T>(this T t, Action<T> action) where T : class
{
if (t != null)
action(t);
return t;
}
public static T? TryDoS<T>(this T? t, Action<T> action) where T : struct
{
if (t != null)
action(t.Value);
return t;
}
Hope it doesn't look like coming from Mars :)
Timespan-related extensions like:
public static TimeSpan Seconds(this int seconds)
{
return TimeSpan.FromSeconds(seconds);
}
public static TimeSpan Minutes(this int minutes)
{
return TimeSpan.FromMinutes(minutes);
}
That allow to use:
1.Seconds()
20.Minutes()
Lock extensions like:
public static IDisposable GetReadLock(this ReaderWriterLockSlim slimLock)
{
slimLock.EnterReadLock();
return new DisposableAction(slimLock.ExitReadLock);
}
public static IDisposable GetWriteLock(this ReaderWriterLockSlim slimLock)
{
slimLock.EnterWriteLock();
return new DisposableAction(slimLock.ExitWriteLock);
}
public static IDisposable GetUpgradeableReadLock(this ReaderWriterLockSlim slimLock)
{
slimLock.EnterUpgradeableReadLock();
return new DisposableAction(slimLock.ExitUpgradeableReadLock);
}
That allow to use locks like:
using (lock.GetUpgradeableReadLock())
{
// try read
using (lock.GetWriteLock())
{
//do write
}
}
And many other from the Lokad Shared Libraries [1]
[1] http://rabdullin.com/shared-libraries/I use these in my Silverlight projects:
public static void Show(this UIElement element)
{
element.Visibility = Visibility.Visible;
}
public static void Hide(this UIElement element)
{
element.Visibility = Visibility.Collapsed;
}
HTH. These are some of my main ones.
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
namespace Insert.Your.Namespace.Here.Helpers
{
public static class Extensions
{
public static bool IsNullOrEmpty<T>(this IEnumerable<T> iEnumerable)
{
// Cheers to Joel Mueller for the bugfix. Was .Count(), now it's .Any()
return iEnumerable == null ||
!iEnumerable.Any();
}
public static IList<T> ToListIfNotNullOrEmpty<T>(this IList<T> iList)
{
return iList.IsNullOrEmpty() ? null : iList;
}
public static PagedList<T> ToPagedListIfNotNullOrEmpty<T>(this PagedList<T> pagedList)
{
return pagedList.IsNullOrEmpty() ? null : pagedList;
}
public static string ToPluralString(this int value)
{
return value == 1 ? string.Empty : "s";
}
public static string ToReadableTime(this DateTime value)
{
TimeSpan span = DateTime.Now.Subtract(value);
const string plural = "s";
if (span.Days > 7)
{
return value.ToShortDateString();
}
switch (span.Days)
{
case 0:
switch (span.Hours)
{
case 0:
if (span.Minutes == 0)
{
return span.Seconds <= 0
? "now"
: string.Format("{0} second{1} ago",
span.Seconds,
span.Seconds != 1 ? plural : string.Empty);
}
return string.Format("{0} minute{1} ago",
span.Minutes,
span.Minutes != 1 ? plural : string.Empty);
default:
return string.Format("{0} hour{1} ago",
span.Hours,
span.Hours != 1 ? plural : string.Empty);
}
default:
return string.Format("{0} day{1} ago",
span.Days,
span.Days != 1 ? plural : string.Empty);
}
}
public static string ToShortGuidString(this Guid value)
{
return Convert.ToBase64String(value.ToByteArray())
.Replace("/", "_")
.Replace("+", "-")
.Substring(0, 22);
}
public static Guid FromShortGuidString(this string value)
{
return new Guid(Convert.FromBase64String(value.Replace("_", "/")
.Replace("-", "+") + "=="));
}
public static string ToStringMaximumLength(this string value, int maximumLength)
{
return ToStringMaximumLength(value, maximumLength, "...");
}
public static string ToStringMaximumLength(this string value, int maximumLength, string postFixText)
{
if (string.IsNullOrEmpty(postFixText))
{
throw new ArgumentNullException("postFixText");
}
return value.Length > maximumLength
? string.Format(CultureInfo.InvariantCulture,
"{0}{1}",
value.Substring(0, maximumLength - postFixText.Length),
postFixText)
:
value;
}
public static string SlugDecode(this string value)
{
return value.Replace("_", " ");
}
public static string SlugEncode(this string value)
{
return value.Replace(" ", "_");
}
}
}
y
) or tooth/teeth .. etc. So it's a helper ... but not the be-all-end-all of a singlular-to-plural modifications. - Pure.Krome
public static class EnumerableExtensions
{
[Pure]
public static U MapReduce<T, U>(this IEnumerable<T> enumerable, Func<T, U> map, Func<U, U, U> reduce)
{
CodeContract.RequiresAlways(enumerable != null);
CodeContract.RequiresAlways(enumerable.Skip(1).Any());
CodeContract.RequiresAlways(map != null);
CodeContract.RequiresAlways(reduce != null);
return enumerable.AsParallel().Select(map).Aggregate(reduce);
}
[Pure]
public static U MapReduce<T, U>(this IList<T> list, Func<T, U> map, Func<U, U, U> reduce)
{
CodeContract.RequiresAlways(list != null);
CodeContract.RequiresAlways(list.Count >= 2);
CodeContract.RequiresAlways(map != null);
CodeContract.RequiresAlways(reduce != null);
U result = map(list[0]);
for (int i = 1; i < list.Count; i++)
{
result = reduce(result,map(list[i]));
}
return result;
}
//Parallel version; creates garbage
[Pure]
public static U MapReduce<T, U>(this IList<T> list, Func<T, U> map, Func<U, U, U> reduce)
{
CodeContract.RequiresAlways(list != null);
CodeContract.RequiresAlways(list.Skip(1).Any());
CodeContract.RequiresAlways(map != null);
CodeContract.RequiresAlways(reduce != null);
U[] mapped = new U[list.Count];
Parallel.For(0, mapped.Length, i =>
{
mapped[i] = map(list[i]);
});
U result = mapped[0];
for (int i = 1; i < list.Count; i++)
{
result = reduce(result, mapped[i]);
}
return result;
}
}
Sometimes its handy to write out a string on a selected element in a list with a custom seperator.
For instance if you have a List<Person>
and want to loop out lastname seperated with a comma you could do this.
string result = string.Empty;
foreach (var person in personList) {
result += person.LastName + ", ";
}
result = result.Substring(0, result.Length - 2);
return result;
Or you could use this handy extension method
public static string Join<T>(this IEnumerable<T> collection, Func<T, string> func, string separator)
{
return String.Join(separator, collection.Select(func).ToArray());
}
And use it like this
personList.Join(x => x.LastName, ", ");
Which produces the same result, in this case a list of lastnames seperated by a comma.
ToDelimitedString
to avoid confusion with the built-in LINQ Join method. - Joel Mueller
Binary search :
public static T BinarySearch<T, TKey>(this IList<T> list, Func<T, TKey> keySelector, TKey key)
where TKey : IComparable<TKey>
{
int min = 0;
int max = list.Count;
int index = 0;
while (min < max)
{
int mid = (max + min) / 2;
T midItem = list[mid];
TKey midKey = keySelector(midItem);
int comp = midKey.CompareTo(key);
if (comp < 0)
{
min = mid + 1;
}
else if (comp > 0)
{
max = mid - 1;
}
else
{
return midItem;
}
}
if (min == max &&
keySelector(list[min]).CompareTo(key) == 0)
{
return list[min];
}
throw new InvalidOperationException("Item not found");
}
Usage (assuming that the list is sorted by Id) :
var item = list.BinarySearch(i => i.Id, 42);
The fact that it throws an InvalidOperationException may seem strange, but that's what Enumerable.First does when there's no matching item.
I just went through all 4 pages of this so far, and I was rather surprised that I didn't see this way to shorten a check for InvokeRequired
:
using System;
using System.Windows.Forms;
/// <summary>
/// Extension methods acting on Control objects.
/// </summary>
internal static class ControlExtensionMethods
{
/// <summary>
/// Invokes the given action on the given control's UI thread, if invocation is needed.
/// </summary>
/// <param name="control">Control on whose UI thread to possibly invoke.</param>
/// <param name="action">Action to be invoked on the given control.</param>
public static void MaybeInvoke(this Control control, Action action)
{
if (control != null && control.InvokeRequired)
{
control.Invoke(action);
}
else
{
action();
}
}
/// <summary>
/// Maybe Invoke a Func that returns a value.
/// </summary>
/// <typeparam name="T">Return type of func.</typeparam>
/// <param name="control">Control on which to maybe invoke.</param>
/// <param name="func">Function returning a value, to invoke.</param>
/// <returns>The result of the call to func.</returns>
public static T MaybeInvoke<T>(this Control control, Func<T> func)
{
if (control != null && control.InvokeRequired)
{
return (T)(control.Invoke(func));
}
else
{
return func();
}
}
}
Usage:
myForm.MaybeInvoke(() => this.Text = "Hello world");
// Sometimes the control might be null, but that's okay.
var dialogResult = this.Parent.MaybeInvoke(() => MessageBox.Show(this, "Yes or no?", "Choice", MessageBoxButtons.YesNo));
Some Date functions:
public static bool IsFuture(this DateTime date, DateTime from)
{
return date.Date > from.Date;
}
public static bool IsFuture(this DateTime date)
{
return date.IsFuture(DateTime.Now);
}
public static bool IsPast(this DateTime date, DateTime from)
{
return date.Date < from.Date;
}
public static bool IsPast(this DateTime date)
{
return date.IsPast(DateTime.Now);
}
Function to compare Files/Directories through the OS File System Info. This is useful to compare shares with local files.
Usage:
DirectoryInfo dir = new DirectoryInfo(@"C:\test\myShareDir");
Console.WriteLine(dir.IsSameFileAs(@"\\myMachineName\myShareDir"));
FileInfo file = new FileInfo(@"C:\test\myShareDir\file.txt");
Console.WriteLine(file.IsSameFileAs(@"\\myMachineName\myShareDir\file.txt"));
Code:
public static class FileExtensions
{
struct BY_HANDLE_FILE_INFORMATION
{
public uint FileAttributes;
public System.Runtime.InteropServices.ComTypes.FILETIME CreationTime;
public System.Runtime.InteropServices.ComTypes.FILETIME LastAccessTime;
public System.Runtime.InteropServices.ComTypes.FILETIME LastWriteTime;
public uint VolumeSerialNumber;
public uint FileSizeHigh;
public uint FileSizeLow;
public uint NumberOfLinks;
public uint FileIndexHigh;
public uint FileIndexLow;
}
//
// CreateFile constants
//
const uint FILE_SHARE_READ = 0x00000001;
const uint OPEN_EXISTING = 3;
const uint GENERIC_READ = (0x80000000);
const uint FILE_FLAG_BACKUP_SEMANTICS = 0x02000000;
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr CreateFile(
string lpFileName,
uint dwDesiredAccess,
uint dwShareMode,
IntPtr lpSecurityAttributes,
uint dwCreationDisposition,
uint dwFlagsAndAttributes,
IntPtr hTemplateFile);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool GetFileInformationByHandle(IntPtr hFile, out BY_HANDLE_FILE_INFORMATION lpFileInformation);
public static bool IsSameFileAs(this FileSystemInfo file, string path)
{
BY_HANDLE_FILE_INFORMATION fileInfo1, fileInfo2;
IntPtr ptr1 = CreateFile(file.FullName, GENERIC_READ, FILE_SHARE_READ, IntPtr.Zero, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, IntPtr.Zero);
if ((int)ptr1 == -1)
{
System.ComponentModel.Win32Exception e = new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error());
throw e;
}
IntPtr ptr2 = CreateFile(path, GENERIC_READ, FILE_SHARE_READ, IntPtr.Zero, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, IntPtr.Zero);
if ((int)ptr2 == -1)
{
System.ComponentModel.Win32Exception e = new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error());
throw e;
}
GetFileInformationByHandle(ptr1, out fileInfo1);
GetFileInformationByHandle(ptr2, out fileInfo2);
return ((fileInfo1.FileIndexHigh == fileInfo2.FileIndexHigh) &&
(fileInfo1.FileIndexLow == fileInfo2.FileIndexLow));
}
}
Pythonic methods for Dictionaries:
/// <summary>
/// If a key exists in a dictionary, return its value,
/// otherwise return the default value for that type.
/// </summary>
public static U GetWithDefault<T, U>(this Dictionary<T, U> dict, T key)
{
return dict.GetWithDefault(key, default(U));
}
/// <summary>
/// If a key exists in a dictionary, return its value,
/// otherwise return the provided default value.
/// </summary>
public static U GetWithDefault<T, U>(this Dictionary<T, U> dict, T key, U defaultValue)
{
return dict.ContainsKey(key)
? dict[key]
: defaultValue;
}
Useful for when you want to append a timestamp to a filename to assure uniqueness.
/// <summary>
/// Format a DateTime as a string that contains no characters
//// that are banned from filenames, such as ':'.
/// </summary>
/// <returns>YYYY-MM-DD_HH.MM.SS</returns>
public static string ToFilenameString(this DateTime dt)
{
return dt.ToString("s").Replace(":", ".").Replace('T', '_');
}
dt.ToString("yyy-MM-dd_HH.mm.ss");
directly to avoid creating 2 additional String instances. Since this format doesn't include a time zone component, a UTC time would be better via dt.ToUniversalTime().ToString(...)
. - devstuff
I use this extension method usually with anonymous types to get a dictionary ala ruby
public static Dictionary<string, object> ToDictionary(this object o)
{
var dictionary = new Dictionary<string, object>();
foreach (var propertyInfo in o.GetType().GetProperties())
{
if (propertyInfo.GetIndexParameters().Length == 0)
{
dictionary.Add(propertyInfo.Name, propertyInfo.GetValue(o, null));
}
}
return dictionary;
}
You can use it
var dummy = new { color = "#000000", width = "100%", id = "myid" };
Dictionary<string, object> dict = dummy.ToDictionary();
And with an extended method as
public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
foreach (T item in source)
{
action(item);
}
}
You can do it
dummy.ToDictionary().ForEach((p) => Console.Write("{0}='{1}' ", p.Key, p.Value));
Output
color='#000000' width='100%' id='myid'
I find myself doing this, over and over, again...
public static bool EqualsIgnoreCase(this string a, string b)
{
return string.Equals(a, b, StringComparison.OrdinalIgnoreCase);
}
...followed by StartsWithIgnoreCase
, EndsWithIgnoreCase
and ContainsIgnoreCase
.
When using a dictionary where the key is a string, return existing key using a case-insensitive search. Our use case for this was for file paths.
/// <summary>
/// Gets the key using <paramref name="caseInsensitiveKey"/> from <paramref name="dictionary"/>.
/// </summary>
/// <typeparam name="T">The dictionary value.</typeparam>
/// <param name="dictionary">The dictionary.</param>
/// <param name="caseInsensitiveKey">The case insensitive key.</param>
/// <returns>
/// An existing key; or <see cref="string.Empty"/> if not found.
/// </returns>
public static string GetKeyIgnoringCase<T>(this IDictionary<string, T> dictionary, string caseInsensitiveKey)
{
if (string.IsNullOrEmpty(caseInsensitiveKey)) return string.Empty;
foreach (string key in dictionary.Keys)
{
if (key.Equals(caseInsensitiveKey, StringComparison.InvariantCultureIgnoreCase))
{
return key;
}
}
return string.Empty;
}
static string Format( this string str,
, params Expression<Func<string,object>>[] args)
{
var parameters = args.ToDictionary
( e=>string.Format("{{{0}}}",e.Parameters[0].Name)
, e=>e.Compile()(e.Parameters[0].Name));
var sb = new StringBuilder(str);
foreach(var kv in parameters)
{
sb.Replace( kv.Key
, kv.Value != null ? kv.Value.ToString() : "");
}
return sb.ToString();
}
With the above extension you can write this:
var str = "{foo} {bar} {baz}".Format(foo=>foo, bar=>2, baz=>new object());
and you'll get "foo 2 System.Object
".
Simple but nicer than "Enumerable.Range", IMHO:
/// <summary>
/// Replace "Enumerable.Range(n)" with "n.Range()":
/// </summary>
/// <param name="n">iterations</param>
/// <returns>0..n-1</returns>
public static IEnumerable<int> Range(this int n)
{
for (int i = 0; i < n; i++)
yield return i;
}
You all probably already know that an interesting usage for extension methods is as a
kind of mixin
[1]. Some extension methods, like the XmlSerializable
, pollute almost every class; and it doesn't make sense to most of them, like Thread
and SqlConnection
.
Some functionality should be explicitly mixed in to the classes that want to have it. I propose a new notation to this kind of type, with the M
prefix.
The XmlSerializable
then, is this:
public interface MXmlSerializable { }
public static class XmlSerializable {
public static string ToXml(this MXmlSerializable self) {
if (self == null) throw new ArgumentNullException();
var serializer = new XmlSerializer(self.GetType());
using (var writer = new StringWriter()) {
serializer.Serialize(writer, self);
return writer.GetStringBuilder().ToString();
}
}
public static T FromXml<T>(string xml) where T : MXmlSerializable {
var serializer = new XmlSerializer(typeof(T));
return (T)serializer.Deserialize(new StringReader(xml));
}
}
A class then mixes it in:
public class Customer : MXmlSerializable {
public string Name { get; set; }
public bool Preferred { get; set; }
}
And the usage is simply:
var customer = new Customer {
Name = "Guybrush Threepwood",
Preferred = true };
var xml = customer.ToXml();
If you like the idea, you can create a new namespace for useful mixins in the project. What do you think?
Oh, and by the way, I think most extension methods should explicitly test for null [2].
[1] http://codecrafter.blogspot.com/2010/02/c-quasi-mixins-pattern.htmlHere's a fun one from our codebase at work. Walk an expensive lazy-eval enumerable on a job thread and push the results back through an observable.
public static IObservable<T> ToAsyncObservable<T>(this IEnumerable<T> @this)
{
return Observable.Create<T>(observer =>
{
var task = new Task(() =>
{
try
{
@this.Run(observer.OnNext);
observer.OnCompleted();
}
catch (Exception e)
{
observer.OnError(e);
}
});
task.Start();
return () => { };
});
}
Silly sample:
new DirectoryInfo(@"c:\program files")
.EnumerateFiles("*", SearchOption.AllDirectories)
.ToAsyncObservable()
.BufferWithTime(TimeSpan.FromSeconds(0.5))
.ObserveOnDispatcher()
.Subscribe(
l => Console.WriteLine("{0} received", l.Count),
() => Console.WriteLine("Done!"));
for (;;)
{
Thread.Sleep(10);
Dispatcher.PushFrame(new DispatcherFrame());
}
Obviously this extension will be useless to you if you aren't using the brilliant Reactive Extensions!
UPDATE thanks to Richard in the comments, this extension method is unnecessary. RX already has an extension method "ToObservable" that takes an IScheduler. Use that instead!
enumerable.ToObservable(Scheduler.TaskPool)
doesn't solve the same problem? - Richard Szalay
Here's another pair I've found endless use for:
public static T ObjectWithMin<T, TResult>(this IEnumerable<T> sequence, Func<T, TResult> predicate)
where T : class
where TResult : IComparable
{
if (!sequence.Any()) return null;
//get the first object with its predicate value
var seed = sequence.Select(x => new {Object = x, Value = predicate(x)}).FirstOrDefault();
//compare against all others, replacing the accumulator with the lesser value
//tie goes to first object found
return
sequence.Select(x => new {Object = x, Value = predicate(x)})
.Aggregate(seed,(acc, x) => acc.Value.CompareTo(x.Value) <= 0 ? acc : x).Object;
}
public static T ObjectWithMax<T, TResult>(this IEnumerable<T> sequence, Func<T, TResult> predicate)
where T : class
where TResult : IComparable
{
if (!sequence.Any()) return null;
//get the first object with its predicate value
var seed = sequence.Select(x => new {Object = x, Value = predicate(x)}).FirstOrDefault();
//compare against all others, replacing the accumulator with the greater value
//tie goes to last object found
return
sequence.Select(x => new {Object = x, Value = predicate(x)})
.Aggregate(seed, (acc, x) => acc.Value.CompareTo(x.Value) > 0 ? acc : x).Object;
}
Usage:
var myObject = myList.ObjectWithMin(x=>x.PropA);
These methods basically replace usages like
var myObject = myList.OrderBy(x=>x.PropA).FirstOrDefault(); //O(nlog(n)) and unstable
and
var myObject = myList.Where(x=>x.PropA == myList.Min(x=>x.PropA)).FirstOrDefault(); //O(N^2) but stable
and
var minValue = myList.Min(x=>x.PropA);
var myObject = myList.Where(x=>x.PropA == minValue).FirstOrDefault(); //not a one-liner, and though linear and stable it's slower (evaluates the enumerable twice)
Here's a bitmap extension which can convert bitmaps to grayscale;
public static Bitmap GrayScale(this Bitmap bitmap)
{
Bitmap newBitmap = new Bitmap(bitmap.Width, bitmap.Height);
Graphics g = Graphics.FromImage(newBitmap);
//the grayscale ColorMatrix
ColorMatrix colorMatrix = new ColorMatrix(new float[][] {
new float[] {.3f, .3f, .3f, 0, 0},
new float[] {.59f, .59f, .59f, 0, 0},
new float[] {.11f, .11f, .11f, 0, 0},
new float[] {0, 0, 0, 1, 0},
new float[] {0, 0, 0, 0, 1}
});
ImageAttributes attributes = new ImageAttributes();
attributes.SetColorMatrix(colorMatrix);
g.DrawImage(bitmap, new Rectangle(0, 0, bitmap.Width, bitmap.Height), 0, 0, bitmap.Width, bitmap.Height, GraphicsUnit.Pixel, attributes);
g.Dispose();
return newBitmap;
}
Sample usage:
Bitmap grayscaled = bitmap.GrayScale()
I didn't want to add anything that was already said, so here are some that I use that haven't been mentioned. (Sorry if this is too lengthy):
public static class MyExtensions
{
public static bool IsInteger(this string input)
{
int temp;
return int.TryParse(input, out temp);
}
public static bool IsDecimal(this string input)
{
decimal temp;
return decimal.TryParse(input, out temp);
}
public static int ToInteger(this string input, int defaultValue)
{
int temp;
return (int.TryParse(input, out temp)) ? temp : defaultValue;
}
public static decimal ToDecimal(this string input, decimal defaultValue)
{
decimal temp;
return (decimal.TryParse(input, out temp)) ? temp : defaultValue;
}
public static DateTime ToFirstOfTheMonth(this DateTime input)
{
return input.Date.AddDays(-1 * input.Day + 1);
}
// Intentionally returns 0 if the target date is before the input date.
public static int MonthsUntil(this DateTime input, DateTime targetDate)
{
input = input.ToFirstOfTheMonth();
targetDate = targetDate.ToFirstOfTheMonth();
int result = 0;
while (input < targetDate)
{
input = input.AddMonths(1);
result++;
}
return result;
}
// Used for backwards compatibility in a system built before my time.
public static DataTable ToDataTable(this IEnumerable input)
{
// too much code to show here right now...
}
}
String.As<T>
, which can be used to convert a string value as some type (intended to be used primarily with primitives and types that support IConvertable. Works great with Nullable
types and even Enums!
public static partial class StringExtensions
{
/// <summary>
/// Converts the string to the specified type, using the default value configured for the type.
/// </summary>
/// <typeparam name="T">Type the string will be converted to. The type must implement IConvertable.</typeparam>
/// <param name="original">The original string.</param>
/// <returns>The converted value.</returns>
public static T As<T>(this String original)
{
return As(original, CultureInfo.CurrentCulture,
default(T));
}
/// <summary>
/// Converts the string to the specified type, using the default value configured for the type.
/// </summary>
/// <typeparam name="T">Type the string will be converted to.</typeparam>
/// <param name="original">The original string.</param>
/// <param name="defaultValue">The default value to use in case the original string is null or empty, or can't be converted.</param>
/// <returns>The converted value.</returns>
public static T As<T>(this String original, T defaultValue)
{
return As(original, CultureInfo.CurrentCulture, defaultValue);
}
/// <summary>
/// Converts the string to the specified type, using the default value configured for the type.
/// </summary>
/// <typeparam name="T">Type the string will be converted to.</typeparam>
/// <param name="original">The original string.</param>
/// <param name="provider">Format provider used during the type conversion.</param>
/// <returns>The converted value.</returns>
public static T As<T>(this String original, IFormatProvider provider)
{
return As(original, provider, default(T));
}
/// <summary>
/// Converts the string to the specified type.
/// </summary>
/// <typeparam name="T">Type the string will be converted to.</typeparam>
/// <param name="original">The original string.</param>
/// <param name="provider">Format provider used during the type conversion.</param>
/// <param name="defaultValue">The default value to use in case the original string is null or empty, or can't be converted.</param>
/// <returns>The converted value.</returns>
/// <remarks>
/// If an error occurs while converting the specified value to the requested type, the exception is caught and the default is returned. It is strongly recommended you
/// do NOT use this method if it is important that conversion failures are not swallowed up.
///
/// This method is intended to be used to convert string values to primatives, not for parsing, converting, or deserializing complex types.
/// </remarks>
public static T As<T>(this String original, IFormatProvider provider,
T defaultValue)
{
T result;
Type type = typeof (T);
if (String.IsNullOrEmpty(original)) result = defaultValue;
else
{
// need to get the underlying type if T is Nullable<>.
if (type.IsNullableType())
{
type = Nullable.GetUnderlyingType(type);
}
try
{
// ChangeType doesn't work properly on Enums
result = type.IsEnum
? (T) Enum.Parse(type, original, true)
: (T) Convert.ChangeType(original, type, provider);
}
catch // HACK: what can we do to minimize or avoid raising exceptions as part of normal operation? custom string parsing (regex?) for well-known types? it would be best to know if you can convert to the desired type before you attempt to do so.
{
result = defaultValue;
}
}
return result;
}
}
This relies on another simple extension for Type
:
/// <summary>
/// Extension methods for <see cref="Type"/>.
/// </summary>
public static class TypeExtensions
{
/// <summary>
/// Returns whether or not the specified type is <see cref="Nullable{T}"/>.
/// </summary>
/// <param name="type">A <see cref="Type"/>.</param>
/// <returns>True if the specified type is <see cref="Nullable{T}"/>; otherwise, false.</returns>
/// <remarks>Use <see cref="Nullable.GetUnderlyingType"/> to access the underlying type.</remarks>
public static bool IsNullableType(this Type type)
{
if (type == null) throw new ArgumentNullException("type");
return type.IsGenericType && type.GetGenericTypeDefinition().Equals(typeof (Nullable<>));
}
}
Usage:
var someInt = "1".As<int>();
var someIntDefault = "bad value".As(1); // "bad value" won't convert, so the default value 1 is returned.
var someEnum = "Sunday".As<DayOfWeek>();
someEnum = "0".As<DayOfWeek>(); // returns Sunday
var someNullableEnum = "".As<DayOfWeek?>(null); // returns a null value since "" can't be converted
I use this a lot with nullable numbers. I helps catch those division by 0, NaN, Infinity...
public static bool IsNullOrDefault<T>(this T? o)
where T : struct
{
return o == null || o.Value.Equals(default(T));
}
I find the following extension method quite useful:
public static T GetService<T>(this IServiceProvider provider)
{
return (T)provider.GetService(typeof(T));
}
It makes it much easier to use the IServiceProvider
interface. Compare:
IProvideValueTarget target = (IProvideValueTarget)serviceProvider(typeof(IProvideValueTarget));
and
var target = serviceProvider.GetService<IProvideValueTarget>();
My suggestion:
public static bool IsNullOrEmpty(this ICollection obj)
{
return (obj == null || obj.Count == 0);
}
Works with collections and arrays:
bool isNullOrEmpty = array.IsNullOrEmpty()
instead of
bool isNullOrEmpty = array == null || array.Length == 0;
Converts a List to a datatable
public static class DataTableConverter
{
/// <summary>
/// Convert a List{T} to a DataTable.
/// </summary>
public static DataTable ToDataTable<T>(this IList<T> items)
{
var tb = new DataTable(typeof(T).Name);
PropertyInfo[] props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (PropertyInfo prop in props)
{
Type t = GetCoreType(prop.PropertyType);
tb.Columns.Add(prop.Name, t);
}
foreach (T item in items)
{
var values = new object[props.Length];
for (int i = 0; i < props.Length; i++)
{
values[i] = props[i].GetValue(item, null);
}
tb.Rows.Add(values);
}
return tb;
}
/// <summary>
/// Determine of specified type is nullable
/// </summary>
public static bool IsNullable(Type t)
{
return !t.IsValueType || (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>));
}
/// <summary>
/// Return underlying type if type is Nullable otherwise return the type
/// </summary>
public static Type GetCoreType(Type t)
{
if (t != null && IsNullable(t))
{
if (!t.IsValueType)
{
return t;
}
else
{
return Nullable.GetUnderlyingType(t);
}
}
else
{
return t;
}
}
}
Usage:
IList<MyClass> myClassList = new List<MyClass>();
DataTable myClassDataTable = myClassList.ToDataTable();
These extension methods invoke an event asynchronously. They were inspired by this StackOverflow answer [1].
/// <summary>
/// Invoke an event asynchronously. Each subscriber to the event will be invoked on a separate thread.
/// </summary>
/// <param name="someEvent">The event to be invoked asynchronously.</param>
/// <param name="sender">The sender of the event.</param>
/// <param name="args">The args of the event.</param>
/// <typeparam name="TEventArgs">The type of <see cref="EventArgs"/> to be used with the event.</typeparam>
public static void InvokeAsync<TEventArgs>(this EventHandler<TEventArgs> someEvent, object sender, TEventArgs args)
where TEventArgs : EventArgs
{
if (someEvent == null)
{
return;
}
var eventListeners = someEvent.GetInvocationList();
AsyncCallback endAsyncCallback = delegate(IAsyncResult iar)
{
var ar = iar as AsyncResult;
if (ar == null)
{
return;
}
var invokedMethod = ar.AsyncDelegate as EventHandler<TEventArgs>;
if (invokedMethod != null)
{
invokedMethod.EndInvoke(iar);
}
};
foreach (EventHandler<TEventArgs> methodToInvoke in eventListeners)
{
methodToInvoke.BeginInvoke(sender, args, endAsyncCallback, null);
}
}
/// <summary>
/// Invoke an event asynchronously. Each subscriber to the event will be invoked on a separate thread.
/// </summary>
/// <param name="someEvent">The event to be invoked asynchronously.</param>
/// <param name="sender">The sender of the event.</param>
/// <param name="args">The args of the event.</param>
public static void InvokeAsync(this EventHandler someEvent, object sender, EventArgs args)
{
if (someEvent == null)
{
return;
}
var eventListeners = someEvent.GetInvocationList();
AsyncCallback endAsyncCallback = delegate(IAsyncResult iar)
{
var ar = iar as AsyncResult;
if (ar == null)
{
return;
}
var invokedMethod = ar.AsyncDelegate as EventHandler;
if (invokedMethod != null)
{
invokedMethod.EndInvoke(iar);
}
};
foreach (EventHandler methodToInvoke in eventListeners)
{
methodToInvoke.BeginInvoke(sender, args, endAsyncCallback, null);
}
}
To use:
public class Foo
{
public event EventHandler<EventArgs> Bar;
public void OnBar()
{
Bar.InvokeAsync(this, EventArgs.Empty);
}
}
Notice the added benefit that you don't have to check for null on the event before invoking it. e.g.:
EventHandler<EventArgs> handler = Bar;
if (handler != null)
{
// Invoke the event
}
To test:
void Main()
{
EventHandler<EventArgs> handler1 =
delegate(object sender, EventArgs args)
{
// Simulate performing work in handler1
Thread.Sleep(100);
Console.WriteLine("Handled 1");
};
EventHandler<EventArgs> handler2 =
delegate(object sender, EventArgs args)
{
// Simulate performing work in handler2
Thread.Sleep(50);
Console.WriteLine("Handled 2");
};
EventHandler<EventArgs> handler3 =
delegate(object sender, EventArgs args)
{
// Simulate performing work in handler3
Thread.Sleep(25);
Console.WriteLine("Handled 3");
};
var foo = new Foo();
foo.Bar += handler1;
foo.Bar += handler2;
foo.Bar += handler3;
foo.OnBar();
Console.WriteLine("Start executing important stuff");
// Simulate performing some important stuff here, where we don't want to
// wait around for the event handlers to finish executing
Thread.Sleep(1000);
Console.WriteLine("Finished executing important stuff");
}
Invoking the event will (usually) yield this output:
Start executing important stuff
Handled 3
Handled 2
Handled 1
Finished executing important stuff
If the event were invoked synchronously, it would always yield this output - and delay execution of the "important" stuff:
[1] https://stackoverflow.com/questions/1916095/how-do-i-make-an-eventhandler-run-asynchronously/1916241#1916241Handled 1
Handled 2
Handled 3
Start executing important stuff
Finished executing important stuff
I actually just
blogged
[1] this today. It's a strongly typed reactive wrapper around a INotifyPropertyChanged
property.
GetPropertyValues
returns an IObservable<T>
of the values as they change, starting with the current value. If ignore the current value, you can just call Skip(1)
on the result.
Usage is like so:
IObservable<int> values = viewModel.GetPropertyValues(x => x.IntProperty);
Implementation:
public static class NotifyPropertyChangeReactiveExtensions
{
// Returns the values of property (an Expression) as they change,
// starting with the current value
public static IObservable<TValue> GetPropertyValues<TSource, TValue>(
this TSource source, Expression<Func<TSource, TValue>> property)
where TSource : INotifyPropertyChanged
{
MemberExpression memberExpression = property.Body as MemberExpression;
if (memberExpression == null)
{
throw new ArgumentException(
"property must directly access a property of the source");
}
string propertyName = memberExpression.Member.Name;
Func<TSource, TValue> accessor = property.Compile();
return source.GetPropertyChangedEvents()
.Where(x => x.EventArgs.PropertyName == propertyName)
.Select(x => accessor(source))
.StartWith(accessor(source));
}
// This is a wrapper around FromEvent(PropertyChanged)
public static IObservable<IEvent<PropertyChangedEventArgs>>
GetPropertyChangedEvents(this INotifyPropertyChanged source)
{
return Observable.FromEvent<PropertyChangedEventHandler,
PropertyChangedEventArgs>(
h => new PropertyChangedEventHandler(h),
h => source.PropertyChanged += h,
h => source.PropertyChanged -= h);
}
}
[1] http://blog.richardszalay.com/2010/10/14/201010creating-strongly-typed-reactive-html/I created a nice Each extension that has the same behavior as jQuery's each function.
It allows something like below, where you can get the index of the current value and break out of the loop by returning false:
new[] { "first", "second", "third" }.Each((value, index) =>
{
if (value.Contains("d"))
return false;
Console.Write(value);
return true;
});
Here's the code
/// <summary>
/// Generic iterator function that is useful to replace a foreach loop with at your discretion. A provided action is performed on each element.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="source"></param>
/// <param name="action">Function that takes in the current value in the sequence.
/// <returns></returns>
public static IEnumerable<T> Each<T>(this IEnumerable<T> source, Action<T> action)
{
return source.Each((value, index) =>
{
action(value);
return true;
});
}
/// <summary>
/// Generic iterator function that is useful to replace a foreach loop with at your discretion. A provided action is performed on each element.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="source"></param>
/// <param name="action">Function that takes in the current value and its index in the sequence.
/// <returns></returns>
public static IEnumerable<T> Each<T>(this IEnumerable<T> source, Action<T, int> action)
{
return source.Each((value, index) =>
{
action(value, index);
return true;
});
}
/// <summary>
/// Generic iterator function that is useful to replace a foreach loop with at your discretion. A provided action is performed on each element.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="source"></param>
/// <param name="action">Function that takes in the current value in the sequence. Returns a value indicating whether the iteration should continue. So return false if you don't want to iterate anymore.</param>
/// <returns></returns>
public static IEnumerable<T> Each<T>(this IEnumerable<T> source, Func<T, bool> action)
{
return source.Each((value, index) =>
{
return action(value);
});
}
/// <summary>
/// Generic iterator function that is useful to replace a foreach loop with at your discretion. A provided action is performed on each element.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="source"></param>
/// <param name="action">Function that takes in the current value and its index in the sequence. Returns a value indicating whether the iteration should continue. So return false if you don't want to iterate anymore.</param>
/// <returns></returns>
public static IEnumerable<T> Each<T>(this IEnumerable<T> source, Func<T, int, bool> action)
{
if (source == null)
return source;
int index = 0;
foreach (var sourceItem in source)
{
if (!action(sourceItem, index))
break;
index++;
}
return source;
}
I use these in my web projects, mainly with MVC. I have a handful of these written for the ViewData and TempData
/// <summary>
/// Checks the Request.QueryString for the specified value and returns it, if none
/// is found then the default value is returned instead
/// </summary>
public static T QueryValue<T>(this HtmlHelper helper, string param, T defaultValue) {
object value = HttpContext.Current.Request.QueryString[param] as object;
if (value == null) { return defaultValue; }
try {
return (T)Convert.ChangeType(value, typeof(T));
} catch (Exception) {
return defaultValue;
}
}
That way I can write something like...
<% if (Html.QueryValue("login", false)) { %>
<div>Welcome Back!</div>
<% } else { %>
<%-- Render the control or something --%>
<% } %>
The Substring method on the string class has always felt inadequate to me. Usually when you do a substring, you know the character(s) from where you want to start, and the charachter(s) where you want to end. Thus, I've always felt that have to specify length as the second parameter is stupid. Therefore, I've written my own extension methods. One that takes a startIndex and an endIndex. And one, that takes a startText (string) and endText (string) so you can just specify the text from where to start the substring, and the text for where to end it.
NOTE: I couldn't name the method Substring as in .NET because my first overload takes the same parameter types as one of the .NET overloads. Therefore I named them Subsetstring. Feel free to add to the CodePlex...
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 > endIndex)
{
throw new InvalidOperationException("End Index must be after Start Index.");
}
if (startIndex < 0)
{
throw new InvalidOperationException("Start Index must be a positive number.");
}
if(endIndex <0)
{
throw new InvalidOperationException("End Index must be a positive number.");
}
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) || string.IsNullOrEmpty(endText))
{
throw new ArgumentException("Start Text and End Text cannot be empty.");
}
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);
}
}
Usage:
string s = "This is a tester for my cool extension method!!";
s = s.Subsetstring("tester", "cool",true);
Output: "tester for my "
While working with MVC and having lots of if
statements where i only care about either true
or false
, and printing null
, or string.Empty
in the other case, I came up with:
public static TResult WhenTrue<TResult>(this Boolean value, Func<TResult> expression)
{
return value ? expression() : default(TResult);
}
public static TResult WhenTrue<TResult>(this Boolean value, TResult content)
{
return value ? content : default(TResult);
}
public static TResult WhenFalse<TResult>(this Boolean value, Func<TResult> expression)
{
return !value ? expression() : default(TResult);
}
public static TResult WhenFalse<TResult>(this Boolean value, TResult content)
{
return !value ? content : default(TResult);
}
It allows me to change <%= (someBool) ? "print y" : string.Empty %>
into <%= someBool.WhenTrue("print y") %>
.
I only use it in my Views where I mix code and HTML, in code files writing the "longer" version is more clear IMHO.
Here is the only extension that I wrote that I use regularly. It makes sending email with System.Net.Mail a bit easier.
public static class MailExtension
{
// GetEmailCreditial(out strServer) gets credentials from an XML file
public static void Send(this MailMessage email)
{
string strServer = String.Empty;
NetworkCredential credentials = GetEmailCreditial(out strServer);
SmtpClient client = new SmtpClient(strServer) { Credentials = credentials };
client.Send(email);
}
public static void Send(this IEnumerable<MailMessage> emails)
{
string strServer = String.Empty;
NetworkCredential credentials = GetEmailCreditial(out strServer);
SmtpClient client = new SmtpClient(strServer) { Credentials = credentials };
foreach (MailMessage email in emails)
client.Send(email);
}
}
// Example of use:
new MailMessage("info@myDomain.com","you@gmail.com","This is an important Subject", "Body goes here").Send();
//Assume email1,email2,email3 are MailMessage objects
new List<MailMessage>(){email1, email2, email}.Send();
Wildcard string comparison:
public static bool MatchesWildcard(this string text, string pattern)
{
int it = 0;
while (text.CharAt(it) != 0 &&
pattern.CharAt(it) != '*')
{
if (pattern.CharAt(it) != text.CharAt(it) && pattern.CharAt(it) != '?')
return false;
it++;
}
int cp = 0;
int mp = 0;
int ip = it;
while (text.CharAt(it) != 0)
{
if (pattern.CharAt(ip) == '*')
{
if (pattern.CharAt(++ip) == 0)
return true;
mp = ip;
cp = it + 1;
}
else if (pattern.CharAt(ip) == text.CharAt(it) || pattern.CharAt(ip) == '?')
{
ip++;
it++;
}
else
{
ip = mp;
it = cp++;
}
}
while (pattern.CharAt(ip) == '*')
{
ip++;
}
return pattern.CharAt(ip) == 0;
}
public static char CharAt(this string s, int index)
{
if (index < s.Length)
return s[index];
return '\0';
}
It's a direct translation of the C code from
this article
[1], hence the CharAt
method that returns 0 for the end of the string
if (fileName.MatchesWildcard("*.cs"))
{
Console.WriteLine("{0} is a C# source file", fileName);
}
[1] http://www.codeproject.com/KB/string/wildcmp.aspxWould be great to have Unix TimeStamp and ISO 8601 formatted date and times. heavily used in websites and rest services.
I use it in my Facebook Library. You can find the source http://github.com/prabirshrestha/FacebookSharp/blob/master/src/FacebookSharp.Core/FacebookUtils/DateUtils.cs
private static readonly DateTime EPOCH = DateTime.SpecifyKind(new DateTime(1970, 1, 1, 0, 0, 0, 0),DateTimeKind.Utc);
public static DateTime FromUnixTimestamp(long timestamp)
{
return EPOCH.AddSeconds(timestamp);
}
public static long ToUnixTimestamp(DateTime date)
{
TimeSpan diff = date.ToUniversalTime() - EPOCH;
return (long)diff.TotalSeconds;
}
public static DateTime FromIso8601FormattedDateTime(string iso8601DateTime){
return DateTime.ParseExact(iso8601DateTime, "o", System.Globalization.CultureInfo.InvariantCulture);
}
public static string ToIso8601FormattedDateTime(DateTime dateTime)
{
return dateTime.ToString("o");
}
Feel free to use in the codeplex project.
Didn't check the whole thread, so it may already be here, but:
public static class FluentOrderingExtensions
public class FluentOrderer<T> : IEnumerable<T>
{
internal List<Comparison<T>> Comparers = new List<Comparison<T>>();
internal IEnumerable<T> Source;
public FluentOrderer(IEnumerable<T> source)
{
Source = source;
}
#region Implementation of IEnumerable
public IEnumerator<T> GetEnumerator()
{
var workingArray = Source.ToArray();
Array.Sort(workingArray, IterativeComparison);
foreach(var element in workingArray) yield return element;
}
private int IterativeComparison(T a, T b)
{
foreach (var comparer in Comparers)
{
var result = comparer(a,b);
if(result != 0) return result;
}
return 0;
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
#endregion
}
public static FluentOrderer<T> OrderFluentlyBy<T,TResult>(this IEnumerable<T> source, Func<T,TResult> predicate)
where TResult : IComparable<TResult>
{
var result = new FluentOrderer<T>(source);
result.Comparers.Add((a,b)=>predicate(a).CompareTo(predicate(b)));
return result;
}
public static FluentOrderer<T> OrderFluentlyByDescending<T,TResult>(this IEnumerable<T> source, Func<T,TResult> predicate)
where TResult : IComparable<TResult>
{
var result = new FluentOrderer<T>(source);
result.Comparers.Add((a,b)=>predicate(a).CompareTo(predicate(b)) * -1);
return result;
}
public static FluentOrderer<T> ThenBy<T, TResult>(this FluentOrderer<T> source, Func<T, TResult> predicate)
where TResult : IComparable<TResult>
{
source.Comparers.Add((a, b) => predicate(a).CompareTo(predicate(b)));
return source;
}
public static FluentOrderer<T> ThenByDescending<T, TResult>(this FluentOrderer<T> source, Func<T, TResult> predicate)
where TResult : IComparable<TResult>
{
source.Comparers.Add((a, b) => predicate(a).CompareTo(predicate(b)) * -1);
return source;
}
}
Usage:
var myFluentlyOrderedList = GetABunchOfComplexObjects()
.OrderFluentlyBy(x=>x.PropertyA)
.ThenByDescending(x=>x.PropertyB)
.ThenBy(x=>x.SomeMethod())
.ThenBy(x=>SomeOtherMethodAppliedTo(x))
.ToList();
... assuming of course that all the predicates return types that are IComparable to themselves. It would work better with a stable sort like a MergeSort instead of .NET's built-in QuickSort, but it provides you with readable multi-field ordering ability similar to SQL (as close as a method chain can get, anyway). You can extend this to accomodate members that aren't IComparable, by defining overloads that take a comparison lambda instead of creating it based on a predicate.
EDIT: A little explanation, since the commenter got some upticks: this set of methods improves upon the basic OrderBy() functionality by allowing you to sort based on multiple fields in descending order of importance. A real-world example would be sorting a list of invoices by customer, then by invoice number (or invoice date). Other methods of getting the data in this order either wouldn't work (OrderBy() uses an unstable sort, so it cannot be chained) or would be inefficient and not look like it does what you're trying to do.
Comparers
into an IComparer<T>
that you pass to a single OrderBy, right? - scobi
Two color extensions I use, mostly for control development:
public static class ColorExtensions
{
// Gets a color that will be readable on top of a given background color
public static Color GetForegroundColor(this Color input)
{
// Math taken from one of the replies to
// http://stackoverflow.com/questions/2241447/make-foregroundcolor-black-or-white-depending-on-background
if (Math.Sqrt(input.R * input.R * .241 + input.G * input.G * .691 + input.B * input.B * .068) > 128)
return Color.Black;
else
return Color.White;
}
// Converts a given Color to gray
public static Color ToGray(this Color input)
{
int g = (int)(input.R * .299) + (int)(input.G * .587) + (int)(input.B * .114);
return Color.FromArgb(input.A, g, g, g);
}
}
Usage:
Color foreColor = someBackColor.GetForegroundColor();
Color grayColor = someBackColor.ToGray();
An easier way to load default settings from a collection (in real life I use it to populate the settings from any source, including the command line, ClickOnce URL parameters etc.):
public static void LoadFrom(this ApplicationSettingsBase settings, NameValueCollection configuration)
{
if (configuration != null)
foreach (string key in configuration.AllKeys)
if (!String.IsNullOrEmpty(key))
try
{
settings[key] = configuration.Get(key);
}
catch (SettingsPropertyNotFoundException)
{
// handle bad arguments as you wish
}
}
Example:
Settings.Default.LoadFrom(new NameValueCollection() { { "Setting1", "Value1" }, { "Setting2", "Value2" } });
Comes in useful for unit testing:
public static IList<T> Clone<T>(this IList<T> list) where T : ICloneable
{
var ret = new List<T>(list.Count);
foreach (var item in list)
ret.Add((T)item.Clone());
// done
return ret;
}
A series of these like TWith2Sugars, alternate shortened syntax:
public static long? ToNullableInt64(this string val)
{
long ret;
return Int64.TryParse(val, out ret) ? ret : new long?();
}
And finally this - is there something already in the BCL that does the following?
public static void Split<T>(this T[] array,
Func<T,bool> determinator,
IList<T> onTrue,
IList<T> onFalse)
{
if (onTrue == null)
onTrue = new List<T>();
else
onTrue.Clear();
if (onFalse == null)
onFalse = new List<T>();
else
onFalse.Clear();
if (determinator == null)
return;
foreach (var item in array)
{
if (determinator(item))
onTrue.Add(item);
else
onFalse.Add(item);
}
}
I'm using this one quite a lot...
Original code:
if (guid != Guid.Empty) return guid;
else return Guid.NewGuid();
New code:
return guid.NewGuidIfEmpty();
Extension method:
public static Guid NewGuidIfEmpty(this Guid uuid)
{
return (uuid != Guid.Empty ? uuid : Guid.NewGuid());
}
These extension methods are pretty useful for me when parsing form input before putting into the database
public static int? ToInt(this string input)
{
int val;
if (int.TryParse(input, out val))
return val;
return null;
}
public static DateTime? ToDate(this string input)
{
DateTime val;
if (DateTime.TryParse(input, out val))
return val;
return null;
}
public static decimal? ToDecimal(this string input)
{
decimal val;
if (decimal.TryParse(input, out val))
return val;
return null;
}
I like these methods for dealing with enums that have the Flags attribute set:
public static bool AnyOf(this object mask, object flags)
{
return ((int)mask & (int)flags) != 0;
}
public static bool AllOf(this object mask, object flags)
{
return ((int)mask & (int)flags) == (int)flags;
}
public static object SetOn(this object mask, object flags)
{
return (int)mask | (int)flags;
}
etc.
Example usage:
var options = SomeOptions.OptionA;
options = options.SetOn(OptionB);
options = options.SetOn(OptionC);
if (options.AnyOf(SomeOptions.OptionA | SomeOptions.OptionB))
{
etc.
The original methods were from this article: http://www.codeproject.com/KB/cs/masksandflags.aspx?display=Print I just converted them to extension methods.
The one problem with them though is that the parameters of object type, which means that all objects end up being extended with these methods, whereas ideally they should only apply to enums.
Update As per the comments, you can get around the "signature pollution", at the expense of performance, like this:
public static bool AnyOf(this Enum mask, object flags)
{
return (Convert.ToInt642(mask) & (int)flags) != 0;
}
object
to just Enum
. - John Leidegren
GetMemberName allows to get the string with the name of a member with compile time safety.
public static string GetMemberName<T, TResult>(
this T anyObject,
Expression<Func<T, TResult>> expression)
{
return ((MemberExpression)expression.Body).Member.Name;
}
Usage:
"blah".GetMemberName(x => x.Length); // returns "Length"
It comes together with a non-extension static method if you don't have a instance:
public static string GetMemberName<T, TReturn>(
Expression<Func<T, TReturn>> expression)
where T : class
{
return ((MemberExpression)expression.Body).Member.Name;
}
But the call doesn't look as pretty of course:
ReflectionUtility.GetMemberName((string) s => s.Length); // returns "Length"
You can put it on Codeplex if you want.
Two little ones (some people find them silly) that I put in all my projects are:
public static bool IsNull(this object o){
return o == null;
}
and
public static bool IsNullOrEmpty(this string s){
return string.IsNullOrEmpty(s);
}
It makes my code so much more fluent..
if (myClassInstance.IsNull()) //... do something
if (myString.IsNullOrEmpty()) //... do something
I think these would make really nice extension properties; if we ever get those.
Reduces the length of a string to toLength
and adds an additional string to the end of the shortened string to denote that the string was shortened (Default ...
)
public static string Shorten(this string str, int toLength, string cutOffReplacement = " ...")
{
if (string.IsNullOrEmpty(str) || str.Length <= toLength)
return str;
else
return str.Remove(toLength) + cutOffReplacement;
}
FindControl with built-in casting:
public static T FindControl<T>(this Control control, string id) where T : Control
{
return (T)control.FindControl(id);
}
It's nothing amazing, but I feel it makes for cleaner code.
// With extension method
container.FindControl<TextBox>("myTextBox").SelectedValue = "Hello world!";
// Without extension method
((TextBox)container.FindControl("myTextBox")).SelectedValue = "Hello world!";
This can be put this in the codeplex project, if so desired
as T
instead of casting - jpbochi
This one can be quite useful :
public static IEnumerable<TResult> Zip<TFirst, TSecond, TResult>(this IEnumerable<TFirst> first, IEnumerable<TSecond> second, Func<TFirst, TSecond, TResult> selector)
{
if (first == null)
throw new ArgumentNullException("first");
if (second == null)
throw new ArgumentNullException("second");
if (selector == null)
throw new ArgumentNullException("selector");
using (var enum1 = first.GetEnumerator())
using (var enum2 = second.GetEnumerator())
{
while (enum1.MoveNext() && enum2.MoveNext())
{
yield return selector(enum1.Current, enum2.Current);
}
}
}
It has been added to the Enumerable
class in .NET 4.0, but it's handy to have it in 3.5.
Example :
var names = new[] { "Joe", "Jane", "Jack", "John" };
var ages = new[] { 42, 22, 18, 33 };
var persons = names.Zip(ages, (n, a) => new { Name = n, Age = a });
foreach (var p in persons)
{
Console.WriteLine("{0} is {1} years old", p.Name, p.Age);
}
yield return
's. The problem is that the ArgumentNullException
's will be thrown at the start of iteration of the returned "query". It should have been thrown at the call to the Zip
method. - jpbochi
Wraps a string every n chars.
public static string WrapAt(this string str, int WrapPos)
{
if (string.IsNullOrEmpty(str))
throw new ArgumentNullException("str", "Cannot wrap a null string");
str = str.Replace("\r", "").Replace("\n", "");
if (str.Length <= WrapPos)
return str;
for (int i = str.Length; i >= 0; i--)
if (i % WrapPos == 0 && i > 0 && i != str.Length)
str = str.Insert(i, "\r\n");
return str;
}
I have implemented a package of extension methods (available at http://foop.codeplex.com/) and some of my daily used ones are:
// the most beloved extension method for me is Pipe:
<%= variable.Pipe(x => this.SomeFunction(x)).Pipe(y =>
{
...;
return this.SomeOtherFunction(y);
}) %>
var d = 28.December(2009); // some extension methods for creating DateTime
DateTime justDatePart = d.JustDate();
TimeSpan justTimePart = d.JustTime();
var nextTime = d.Add(5.Hours());
using(StreamReader reader = new StreamReader("lines-of-data-file-for-example")) {
...
// for reading streams line by line and usable in LINQ
var query = from line in reader.Lines();
where line.Contains(_today)
select new { Parts = PartsOf(line), Time = _now };
}
500.Sleep();
XmlSerialize and XmlDeserialize
IsNull and IsNotNull
IfTrue, IfFalse and Iff:
true.IfTrue(() => Console.WriteLine("it is true then!");
IfNull and IfNotNull
Where
on a single value, though. Could someone edit the answer to make this point clearer? - jpbochi
NullPartial HTML helper for ASP MVC.
When passed a null Model, HTML.Partial and HTML.RenderPartial will provide the View's model, if this partial is strongly typed and the View has a different type it will throw an exception rather than passing a null reference. These helpers let you specify two different partials so you can keep your null tests out of the view.
You have permission to include this on the Codeplex page
public static class nullpartials
{
public static MvcHtmlString NullPartial(this HtmlHelper helper, string Partial, string NullPartial, object Model)
{
if (Model == null)
return helper.Partial(NullPartial);
else
return helper.Partial(Partial, Model);
}
public static MvcHtmlString NullPartial(this HtmlHelper helper, string Partial, string NullPartial, object Model, ViewDataDictionary viewdata)
{
if (Model == null)
return helper.Partial(NullPartial, viewdata);
else
return helper.Partial(Partial, Model, viewdata);
}
public static void RenderNullPartial(this HtmlHelper helper, string Partial, string NullPartial, object Model)
{
if (Model == null)
{
helper.RenderPartial(NullPartial);
return;
}
else
{
helper.RenderPartial(Partial, Model);
return;
}
}
public static void RenderNullPartial(this HtmlHelper helper, string Partial, string NullPartial, object Model, ViewDataDictionary viewdata)
{
if (Model == null)
{
helper.RenderPartial(NullPartial, viewdata);
return;
}
else
{
helper.RenderPartial(Partial, Model, viewdata);
return;
}
}
}
I am sure this has been done before, but I find myself using this method (and simpler derivatives) often:
public static bool CompareEx(this string strA, string strB, CultureInfo culture, bool ignoreCase)
{
return string.Compare(strA, strB, ignoreCase, culture) == 0;
}
You can write it in a number of ways, but I like it because it very quickly unifies my approach to comparing strings while saving me lines of code (or characters of code).
My most used extension is one which can format byte arrays:
/// <summary>
/// Returns a string representation of a byte array.
/// </summary>
/// <param name="bytearray">The byte array to represent.</param>
/// <param name="subdivision">The number of elements per group,
/// or 0 to not restrict it. The default is 0.</param>
/// <param name="subsubdivision">The number of elements per line,
/// or 0 to not restrict it. The default is 0.</param>
/// <param name="divider">The string dividing the individual bytes. The default is " ".</param>
/// <param name="subdivider">The string dividing the groups. The default is " ".</param>
/// <param name="subsubdivider">The string dividing the lines. The default is "\r\n".</param>
/// <param name="uppercase">Whether the representation is in uppercase hexadecimal.
/// The default is <see langword="true"/>.</param>
/// <param name="prebyte">The string to put before each byte. The default is an empty string.</param>
/// <param name="postbyte">The string to put after each byte. The default is an empty string.</param>
/// <returns>The string representation.</returns>
/// <exception cref="ArgumentNullException">
/// <paramref name="bytearray"/> is <see langword="null"/>.
/// </exception>
public static string ToArrayString(this byte[] bytearray,
int subdivision = 0,
int subsubdivision = 0,
string divider = " ",
string subdivider = " ",
string subsubdivider = "\r\n",
bool uppercase = true,
string prebyte = "",
string postbyte = "")
{
#region Contract
if (bytearray == null)
throw new ArgumentNullException("bytearray");
#endregion
StringBuilder sb = new StringBuilder(
bytearray.Length * (2 + divider.Length + prebyte.Length + postbyte.Length) +
(subdivision > 0 ? (bytearray.Length / subdivision) * subdivider.Length : 0) +
(subsubdivision > 0 ? (bytearray.Length / subsubdivision) * subsubdivider.Length : 0));
int groupElements = (subdivision > 0 ? subdivision - 1 : -1);
int lineElements = (subsubdivision > 0 ? subsubdivision - 1 : -1);
for (long i = 0; i < bytearray.LongLength - 1; i++)
{
sb.Append(prebyte);
sb.Append(String.Format(CultureInfo.InvariantCulture, (uppercase ? "{0:X2}" : "{0:x2}"), bytearray[i]));
sb.Append(postbyte);
if (lineElements == 0)
{
sb.Append(subsubdivider);
groupElements = subdivision;
lineElements = subsubdivision;
}
else if (groupElements == 0)
{
sb.Append(subdivider);
groupElements = subdivision;
}
else
sb.Append(divider);
lineElements--;
groupElements--;
}
sb.Append(prebyte);
sb.Append(String.Format(CultureInfo.InvariantCulture, (uppercase ? "{0:X2}" : "{0:x2}"), bytearray[bytearray.LongLength - 1]));
sb.Append(postbyte);
return sb.ToString();
}
By default ToArrayString()
just prints the byte array as a long string of individual bytes. However, ToArrayString(4, 16)
groups the bytes in groups of four, with 16 bytes on a line, just as it is in your favorite hex editor. And the following nicely formats the byte array for usage in C# code:
byte[] bytearray = new byte[]{ ... };
Console.Write(bytearray.ToArrayString(4, 16, ", ", ", ", ",\r\n", true, "0x"));
It was written by me, so you may put it on Codeplex.
this
parameter) ! IMHO, any method with more than 4 parameters needs refactoring... - Thomas Levesque
Inspired by String.IsNullOrEmpty
To validate the given List is null or empty
public static bool IsNullOrEmpty<TSource>(this List<TSource> src)
{
return (src == null || src.Count == 0);
}
And this one is to validate given 2 files and properties
public static bool Compare(this FileInfo f1, FileInfo f2, string propertyName)
{
try
{
PropertyInfo p1 = f1.GetType().GetProperty(propertyName);
PropertyInfo p2 = f2.GetType().GetProperty(propertyName);
if (p1.GetValue(f1, null) == p2.GetValue(f1, null))
return true;
}
catch (Exception ex)
{
return false;
}
return false;
}
And use it like this
FileInfo fo = new FileInfo("c:\\netlog.txt");
FileInfo f1 = new FileInfo("c:\\regkey.txt");
fo.compare(f1, "CreationTime");
public static bool CompareByProperty<Tself, Tother>(this Tself self, Tother other, string propertyName)
but you will have to change the comparison to use Equals(value1, value2)
instead of ==
since == compares the reference for object types: stackoverflow.com/questions/814878/… - Jürgen Steinblock
IsNullOrEmpty<T>()
that accepts an IEnumerable<T>
? - jpbochi
? true : false
. - jpbochi
catch
. If an exception is thrown, let the caller decide how to handle it. - Greg
For raising events concisely:
public static void Raise(this EventHandler handler, object sender, EventArgs e)
{
if (handler != null)
{
handler(sender, e);
}
}
public static void Raise<T>(this EventHandler<T> handler, object sender, T e) where T : EventArgs
{
if (handler != null)
{
handler(sender, e);
}
}
Usage:
public event EventHandler Bar;
public void Foo()
{
Bar.Raise(this, EventArgs.Empty);
}
There's a bit of discussion about potential thread-safety issues here [1]. Since .NET 4, the above form is thread-safe, but requires rearranging and some locks if using an older version.
[1] https://stackoverflow.com/questions/2123608/is-this-a-valid-pattern-for-raising-events-in-cprotected virtual void OnBar(Eventargs e)
pattern outlined here: msdn.microsoft.com/en-us/library/hy3sefw3%28VS.80%29.aspx. - Will Vousden
I've written like a quad zillion extension methods, so here are a few ones I find particulary usefull. Feel free to implement.
public static class ControlExtenders
{
/// <summary>
/// Advanced version of find control.
/// </summary>
/// <typeparam name="T">Type of control to find.</typeparam>
/// <param name="id">Control id to find.</param>
/// <returns>Control of given type.</returns>
/// <remarks>
/// If the control with the given id is not found
/// a new control instance of the given type is returned.
/// </remarks>
public static T FindControl<T>(this Control control, string id) where T : Control
{
// User normal FindControl method to get the control
Control _control = control.FindControl(id);
// If control was found and is of the correct type we return it
if (_control != null && _control is T)
{
// Return new control
return (T)_control;
}
// Create new control instance
_control = (T)Activator.CreateInstance(typeof(T));
// Add control to source control so the
// next it is found and the value can be
// passed on itd, remember to hide it and
// set an ID so it can be found next time
if (!(_control is ExtenderControlBase))
{
_control.Visible = false;
}
_control.ID = id;
control.Controls.Add(_control);
// Use reflection to create a new instance of the control
return (T)_control;
}
}
public static class GenericListExtenders
{
/// <summary>
/// Sorts a generic list by items properties.
/// </summary>
/// <typeparam name="T">Type of collection.</typeparam>
/// <param name="list">Generic list.</param>
/// <param name="fieldName">Field to sort data on.</param>
/// <param name="sortDirection">Sort direction.</param>
/// <remarks>
/// Use this method when a dinamyc sort field is requiered. If the
/// sorting field is known manual sorting might improve performance.
/// </remarks>
public static void SortObjects<T>(this List<T> list, string fieldName, SortDirection sortDirection)
{
PropertyInfo propInfo = typeof(T).GetProperty(fieldName);
if (propInfo != null)
{
Comparison<T> compare = delegate(T a, T b)
{
bool asc = sortDirection == SortDirection.Ascending;
object valueA = asc ? propInfo.GetValue(a, null) : propInfo.GetValue(b, null);
object valueB = asc ? propInfo.GetValue(b, null) : propInfo.GetValue(a, null);
return valueA is IComparable ? ((IComparable)valueA).CompareTo(valueB) : 0;
};
list.Sort(compare);
}
}
/// <summary>
/// Creates a pagged collection from generic list.
/// </summary>
/// <typeparam name="T">Type of collection.</typeparam>
/// <param name="list">Generic list.</param>
/// <param name="sortField">Field to sort data on.</param>
/// <param name="sortDirection">Sort direction.</param>
/// <param name="from">Page from item index.</param>
/// <param name="to">Page to item index.</param>
/// <param name="copy">Creates a copy and returns a new list instead of changing the current one.</param>
/// <returns>Pagged list collection.</returns>
public static List<T> Page<T>(this List<T> list, string sortField, bool sortDirection, int from, int to, bool copy)
{
List<T> _pageList = new List<T>();
// Copy list
if (copy)
{
T[] _arrList = new T[list.Count];
list.CopyTo(_arrList);
_pageList = new List<T>(_arrList);
}
else
{
_pageList = list;
}
// Make sure there are enough items in the list
if (from > _pageList.Count)
{
int diff = Math.Abs(from - to);
from = _pageList.Count - diff;
}
if (to > _pageList.Count)
{
to = _pageList.Count;
}
// Sort items
if (!string.IsNullOrEmpty(sortField))
{
SortDirection sortDir = SortDirection.Descending;
if (!sortDirection) sortDir = SortDirection.Ascending;
_pageList.SortObjects(sortField, sortDir);
}
// Calculate max number of items per page
int count = to - from;
if (from + count > _pageList.Count) count -= (from + count) - _pageList.Count;
// Get max number of items per page
T[] pagged = new T[count];
_pageList.CopyTo(from, pagged, 0, count);
// Return pagged items
return new List<T>(pagged);
}
/// <summary>
/// Shuffle's list items.
/// </summary>
/// <typeparam name="T">List type.</typeparam>
/// <param name="list">Generic list.</param>
public static void Shuffle<T>(this List<T> list)
{
Random rng = new Random();
for (int i = list.Count - 1; i > 0; i--)
{
int swapIndex = rng.Next(i + 1);
if (swapIndex != i)
{
T tmp = list[swapIndex];
list[swapIndex] = list[i];
list[i] = tmp;
}
}
}
/// <summary>
/// Converts generic List to DataTable.
/// </summary>
/// <typeparam name="T">Type.</typeparam>
/// <param name="list">Generic list.</param>
/// <param name="columns">Name of the columns to copy to the DataTable.</param>
/// <returns>DataTable.</returns>
public static DataTable ToDataTable<T>(this List<T> list, string[] columns)
{
List<string> _columns = new List<string>(columns);
DataTable dt = new DataTable();
foreach (PropertyInfo info in typeof(T).GetProperties())
{
if (_columns.Contains(info.Name) || columns == null)
{
dt.Columns.Add(new DataColumn(info.Name, info.PropertyType));
}
}
foreach (T t in list)
{
DataRow row = dt.NewRow();
foreach (PropertyInfo info in typeof(T).GetProperties())
{
if (_columns.Contains(info.Name) || columns == null)
{
row[info.Name] = info.GetValue(t, null);
}
}
dt.Rows.Add(row);
}
return dt;
}
}
public static class DateTimeExtenders
{
/// <summary>
/// Returns number of month from a string representation.
/// </summary>
/// <returns>Number of month.</returns>
public static int MonthToNumber(this DateTime datetime, string month)
{
month = month.ToLower();
for (int i = 1; i <= 12; i++)
{
DateTime _dt = DateTime.Parse("1." + i + ".2000");
string _month = CultureInfo.InvariantCulture.DateTimeFormat.GetMonthName(i).ToLower();
if (_month == month)
{
return i;
}
}
return 0;
}
/// <summary>
/// Returns month name from month number.
/// </summary>
/// <returns>Name of month.</returns>
public static string MonthToName(this DateTime datetime, int month)
{
for (int i = 1; i <= 12; i++)
{
if (i == month)
{
return CultureInfo.InvariantCulture.DateTimeFormat.GetMonthName(i);
}
}
return "";
}
}
public static class ObjectExtender
{
public static object CloneBinary<T>(this T originalObject)
{
using (var stream = new System.IO.MemoryStream())
{
BinaryFormatter binaryFormatter = new BinaryFormatter();
binaryFormatter.Serialize(stream, originalObject);
stream.Position = 0;
return (T)binaryFormatter.Deserialize(stream);
}
}
public static object CloneObject(this object obj)
{
using (MemoryStream memStream = new MemoryStream())
{
BinaryFormatter binaryFormatter = new BinaryFormatter(null, new StreamingContext(StreamingContextStates.Clone));
binaryFormatter.Serialize(memStream, obj);
memStream.Position = 0;
return binaryFormatter.Deserialize(memStream);
}
}
}
public static class StringExtenders
{
/// <summary>
/// Returns string as unit.
/// </summary>
/// <param name="value">Value.</param>
/// <returns>Unit</returns>
public static Unit ToUnit(this string value)
{
// Return empty unit
if (string.IsNullOrEmpty(value))
return Unit.Empty;
// Trim value
value = value.Trim();
// Return pixel unit
if (value.EndsWith("px"))
{
// Set unit type
string _int = value.Replace("px", "");
// Try parsing to int
double _val = 0;
if (!double.TryParse(_int, out _val))
{
// Invalid value
return Unit.Empty;
}
// Return unit
return new Unit(_val, UnitType.Pixel);
}
// Return percent unit
if (value.EndsWith("%"))
{
// Set unit type
string _int = value.Replace("%", "");
// Try parsing to int
double _val = 0;
if (!double.TryParse(_int, out _val))
{
// Invalid value
return Unit.Empty;
}
// Return unit
return new Unit(_val, UnitType.Percentage);
}
// No match found
return new Unit();
}
/// <summary>
/// Returns alternative string if current string is null or empty.
/// </summary>
/// <param name="str"></param>
/// <param name="alternative"></param>
/// <returns></returns>
public static string Alternative(this string str, string alternative)
{
if (string.IsNullOrEmpty(str)) return alternative;
return str;
}
/// <summary>
/// Removes all HTML tags from string.
/// </summary>
/// <param name="html">String containing HTML tags.</param>
/// <returns>String with no HTML tags.</returns>
public static string StripHTML(this string html)
{
string nohtml = Regex.Replace(html, "<(.|\n)*?>", "");
nohtml = nohtml.Replace("\r\n", "").Replace("\n", "").Replace(" ", "").Trim();
return nohtml;
}
}
The first one is my favourite as it enables me to replace:
Control c = this.FindControl("tbName");
if (c != null)
{
// Do something with c
customer.Name = ((TextBox)c).Text;
}
With this:
TextBox c = this.FindControl<TextBox>("tbName");
customer.Name = c.Text;
Settings default string values:
string str = "";
if (string.IsNullOrEmpty(str))
{
str = "I'm empty!";
}
Becomes:
str = str.Alternative("I'm empty!");
Here are a couple of methods that I use to make extracting single attributes a little less painful:
public static T GetAttribute<T>(this ICustomAttributeProvider provider, bool inherit = false, int index = 0) where T : Attribute
{
return provider.GetAttribute(typeof(T), inherit, index) as T;
}
public static Attribute GetAttribute(this ICustomAttributeProvider provider, Type type, bool inherit = false, int index = 0)
{
bool exists = provider.IsDefined(type, inherit);
if (!exists)
{
return null;
}
object[] attributes = provider.GetCustomAttributes(type, inherit);
if (attributes != null && attributes.Length != 0)
{
return attributes[index] as Attribute;
}
else
{
return null;
}
}
Usage (implementation of this [1] enum description hack):
public static string GetDescription(this Enum value)
{
var fieldInfo = value.GetType().GetField(value.ToString());
var attribute = fieldInfo.GetAttribute<DescriptionAttribute>();
return attribute != null ? attribute.Description : null;
}
Feel free to include this in the CodePlex project!
[1] http://blog.spontaneouspublicity.com/post/2008/01/17/Associating-Strings-with-enums-in-C.aspxI thought I'd seen this somewhere before, but couldn't find it suggested anywhere here. MS has a TryGetValue function on the IDictionary interface, but it returns a bool and gives the value in an out
parameter, so here's a simpler, cleaner implementation:
public static TVal GetValueOrDefault<TKey, TVal>(this IDictionary<TKey, TVal> d, TKey key) {
if (d.ContainsKey(key))
return d[key];
return default(TVal);
}
TryXxx
have an out
parameter and bool
result: that is the whole point of that pattern! Your method should be called something like DefaultGetValue
to set it apart from TryGetValue
. - Jeroen Wiert Pluimers
GetValueOrDefault
to be more in line with other similar methods like FirstOrDefault
- Davy8
Here's another control-extension i've been using though i don't know if it's posted here before.
public static class ControlExtensions
{
public static void DoubleBuffer(this Control control)
{
// http://stackoverflow.com/questions/76993/how-to-double-buffer-net-controls-on-a-form/77233#77233
// Taxes: Remote Desktop Connection and painting: http://blogs.msdn.com/oldnewthing/archive/2006/01/03/508694.aspx
if (System.Windows.Forms.SystemInformation.TerminalServerSession) return;
System.Reflection.PropertyInfo dbProp = typeof(System.Windows.Forms.Control).GetProperty("DoubleBuffered", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
dbProp.SetValue(control, true, null);
}
}
usage:
this.someControl.DoubleBuffer();
I've been looking for a way to contribute back to the community some of the things I've developed.
Here's some FileInfo extensions that I find quite useful.
/// <summary>
/// Open with default 'open' program
/// </summary>
/// <param name="value"></param>
public static Process Open(this FileInfo value)
{
if (!value.Exists)
throw new FileNotFoundException("File doesn't exist");
Process p = new Process();
p.StartInfo.FileName = value.FullName;
p.StartInfo.Verb = "Open";
p.Start();
return p;
}
/// <summary>
/// Print the file
/// </summary>
/// <param name="value"></param>
public static void Print(this FileInfo value)
{
if (!value.Exists)
throw new FileNotFoundException("File doesn't exist");
Process p = new Process();
p.StartInfo.FileName = value.FullName;
p.StartInfo.Verb = "Print";
p.Start();
}
/// <summary>
/// Send this file to the Recycle Bin
/// </summary>
/// <exception cref="File doesn't exist" />
/// <param name="value"></param>
public static void Recycle(this FileInfo value)
{
value.Recycle(false);
}
/// <summary>
/// Send this file to the Recycle Bin
/// On show, if person refuses to send file to the recycle bin,
/// exception is thrown or otherwise delete fails
/// </summary>
/// <exception cref="File doesn't exist" />
/// <exception cref="On show, if user refuses, throws exception 'The operation was canceled.'" />
/// <param name="value">File being recycled</param>
/// <param name="showDialog">true to show pop-up</param>
public static void Recycle(this FileInfo value, bool showDialog)
{
if (!value.Exists)
throw new FileNotFoundException("File doesn't exist");
if( showDialog )
FileSystem.DeleteFile
(value.FullName, UIOption.AllDialogs,
RecycleOption.SendToRecycleBin);
else
FileSystem.DeleteFile
(value.FullName, UIOption.OnlyErrorDialogs,
RecycleOption.SendToRecycleBin);
}
Open any file in the user's favorite editor:
new FileInfo("C:\image.jpg").Open();
Print any file that the operating system knows how to print:
new FileInfo("C:\image.jpg").Print();
Send any file to the recycle bin:
Microsoft.VisualBasic
referenceusing Microsoft.VisualBasic.FileIO;
Example:
new FileInfo("C:\image.jpg").Recycle();
Or
// let user have a chance to cancel send to recycle bin.
new FileInfo("C:\image.jpg").Recycle(true);
Open
, but these are still good extensions and I'm surprised that nobody has posted them before. - leviathanbadger
In .NET, there is a
IndexOf
[1] and a
LastIndexOf
[2] methods that return the index of the first and the last occurrence of a match in a String
object. I have an extension method to get the index of the nth occurrence:
public static partial class StringExtensions {
public static int NthIndexOf(this String str, String match, int occurrence) {
int i = 1;
int index = 0;
while (i <= occurrence &&
( index = str.IndexOf(match, index + 1) ) != -1) {
if (i == occurrence) {
// Occurrence match found!
return index;
}
i++;
}
// Match not found
return -1;
}
}
[1] http://msdn.microsoft.com/en-us/library/k8b1470s.aspxUsed in winforms to fill a comboBox:
List<MyObject> myObjects = new List<MyObject>() {
new MyObject() {Name = "a", Id = 0},
new MyObject() {Name = "b", Id = 1},
new MyObject() {Name = "c", Id = 2} }
comboBox.FillDataSource<MyObject>(myObjects, x => x.Name);
The extension method:
/** <summary>Fills the System.Windows.Forms.ComboBox object DataSource with a
* list of T objects.</summary>
* <param name="values">The list of T objects.</param>
* <param name="displayedValue">A function to apply to each element to get the
* display value.</param>
*/
public static void FillDataSource<T>(this ComboBox comboBox, List<T> values,
Func<T, String> displayedValue) {
// Create dataTable
DataTable data = new DataTable();
data.Columns.Add("ValueMember", typeof(T));
data.Columns.Add("DisplayMember");
for (int i = 0; i < values.Count; i++) {
// For each value/displayed value
// Create new row with value & displayed value
DataRow dr = data.NewRow();
dr["ValueMember"] = values[i];
dr["DisplayMember"] = displayedValue(values[i]) ?? "";
// Add row to the dataTable
data.Rows.Add(dr);
}
// Bind datasource to the comboBox
comboBox.DataSource = data;
comboBox.ValueMember = "ValueMember";
comboBox.DisplayMember = "DisplayMember";
}
I like these NUnit Assert extensions: http://svn.caffeine-it.com/openrasta/trunk/src/Rasta.Testing/AssertExtensions.cs
Here is another ThrowIfNull implementation:
[ThreadStatic]
private static string lastMethodName = null;
[ThreadStatic]
private static int lastParamIndex = 0;
[MethodImpl(MethodImplOptions.NoInlining)]
public static void ThrowIfNull<T>(this T parameter)
{
var currentStackFrame = new StackFrame(1);
var props = currentStackFrame.GetMethod().GetParameters();
if (!String.IsNullOrEmpty(lastMethodName)) {
if (currentStackFrame.GetMethod().Name != lastMethodName) {
lastParamIndex = 0;
} else if (lastParamIndex >= props.Length - 1) {
lastParamIndex = 0;
} else {
lastParamIndex++;
}
} else {
lastParamIndex = 0;
}
if (!typeof(T).IsValueType) {
for (int i = lastParamIndex; i < props.Length; i++) {
if (props[i].ParameterType.IsValueType) {
lastParamIndex++;
} else {
break;
}
}
}
if (parameter == null) {
string paramName = props[lastParamIndex].Name;
throw new ArgumentNullException(paramName);
}
lastMethodName = currentStackFrame.GetMethod().Name;
}
It's not as efficient as the other impementations, but has cleaner usage:
public void Foo()
{
Bar(1, 2, "Hello", "World"); //no exception
Bar(1, 2, "Hello", null); //exception
Bar(1, 2, null, "World"); //exception
}
public void Bar(int x, int y, string someString1, string someString2)
{
//will also work with comments removed
//x.ThrowIfNull();
//y.ThrowIfNull();
someString1.ThrowIfNull();
someString2.ThrowIfNull();
//Do something incredibly useful here!
}
Changing the parameters to int? will also work.
-bill
Some extensions for working with lists:
/// <summary>
/// Wrap an object in a list
/// </summary>
public static IList<T> WrapInList<T>(this T item)
{
List<T> result = new List<T>();
result.Add(item);
return result;
}
use eg:
myList = someObject.InList();
To make an IEnumerable that contains items from one or more sources, in order to make IEnumerable work more like lists. This may not be a good idea for high-performance code but useful for making tests:
public static IEnumerable<T> Append<T>(this IEnumerable<T> enumerable, T newItem)
{
foreach (T item in enumerable)
{
yield return item;
}
yield return newItem;
}
public static IEnumerable<T> Append<T>(this IEnumerable<T> enumerable, params T[] newItems)
{
foreach (T item in enumerable)
{
yield return item;
}
foreach (T newItem in newItems)
{
yield return newItem;
}
}
use e.g.
someEnumeration = someEnumeration.Append(newItem);
Other variations of this are possible - e.g.
someEnumeration = someEnumeration.Append(otherEnumeration);
If you are cloning items, you may also want to clone lists of them:
public static IList<T> Clone<T>(this IEnumerable<T> source) where T: ICloneable
{
List<T> result = new List<T>();
foreach (T item in source)
{
result.Add((T)item.Clone());
}
return result;
}
When I am working with ObservableCollection<T>
, I generally extend it with an AddRange method. Other answers here give implementations of this.
You may put this code in the Codeplex project if you want.
Append()
(and use iterator blocks as suggested by peSHlr) - Joel Coehoorn
This is an extension method for the ASP.Net MVC action link helper method that allows it to use the controller's authorize attributes to decide if the link should be enabled, disabled or hidden from the current user's view. I saves you from having to enclose your restricted actions in "if" clauses that check for user membership in all the views. Thanks to Maarten Balliauw [1] for the idea and the code bits that showed me the way :)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Security.Principal;
using System.Web.Routing;
using System.Web.Mvc;
using System.Collections;
using System.Reflection;
namespace System.Web.Mvc.Html
{
public static class HtmlHelperExtensions
{
/// <summary>
/// Shows or hides an action link based on the user's membership status
/// and the controller's authorize attributes
/// </summary>
/// <param name="linkText">The link text.</param>
/// <param name="action">The controller action name.</param>
/// <param name="controller">The controller name.</param>
/// <returns></returns>
public static string SecurityTrimmedActionLink(
this HtmlHelper htmlHelper,
string linkText,
string action,
string controller)
{
return SecurityTrimmedActionLink(htmlHelper, linkText, action, controller, false, null);
}
/// <summary>
/// Enables, disables or hides an action link based on the user's membership status
/// and the controller's authorize attributes
/// </summary>
/// <param name="linkText">The link text.</param>
/// <param name="action">The action name.</param>
/// <param name="controller">The controller name.</param>
/// <param name="showDisabled">if set to <c>true</c> [show link as disabled -
/// using a span tag instead of an anchor tag ].</param>
/// <param name="disabledAttributeText">Use this to add attributes to the disabled
/// span tag.</param>
/// <returns></returns>
public static string SecurityTrimmedActionLink(
this HtmlHelper htmlHelper,
string linkText,
string action,
string controller,
bool showDisabled,
string disabledAttributeText)
{
if (IsAccessibleToUser(action, controller, HttpContext.Current ))
{
return htmlHelper.ActionLink(linkText, action, controller);
}
else
{
return showDisabled ?
String.Format(
"<span{1}>{0}</span>",
linkText,
disabledAttributeText==null?"":" "+disabledAttributeText
) : "";
}
}
private static IController GetControllerInstance(string controllerName)
{
Assembly assembly = Assembly.GetExecutingAssembly();
Type controllerType = GetControllerType(controllerName);
return (IController)Activator.CreateInstance(controllerType);
}
private static ArrayList GetControllerAttributes(string controllerName, HttpContext context)
{
if (context.Cache[controllerName + "_ControllerAttributes"] == null)
{
var controller = GetControllerInstance(controllerName);
context.Cache.Add(
controllerName + "_ControllerAttributes",
new ArrayList(controller.GetType().GetCustomAttributes(typeof(AuthorizeAttribute), true)),
null,
Caching.Cache.NoAbsoluteExpiration,
Caching.Cache.NoSlidingExpiration,
Caching.CacheItemPriority.Default,
null);
}
return (ArrayList)context.Cache[controllerName + "_ControllerAttributes"];
}
private static ArrayList GetMethodAttributes(string controllerName, string actionName, HttpContext context)
{
if (context.Cache[controllerName + "_" + actionName + "_ActionAttributes"] == null)
{
ArrayList actionAttrs = new ArrayList();
var controller = GetControllerInstance(controllerName);
MethodInfo[] methods = controller.GetType().GetMethods();
foreach (MethodInfo method in methods)
{
object[] attributes = method.GetCustomAttributes(typeof(ActionNameAttribute), true);
if ((attributes.Length == 0 && method.Name == actionName)
||
(attributes.Length > 0 && ((ActionNameAttribute)attributes[0]).Name == actionName))
{
actionAttrs.AddRange(method.GetCustomAttributes(typeof(AuthorizeAttribute), true));
}
}
context.Cache.Add(
controllerName + "_" + actionName + "_ActionAttributes",
actionAttrs,
null,
Caching.Cache.NoAbsoluteExpiration,
Caching.Cache.NoSlidingExpiration,
Caching.CacheItemPriority.Default,
null);
}
return (ArrayList)context.Cache[controllerName + "_" + actionName+ "_ActionAttributes"];
}
public static bool IsAccessibleToUser(string actionToAuthorize, string controllerToAuthorize, HttpContext context)
{
IPrincipal principal = context.User;
//cache the attribute list for both controller class and it's methods
ArrayList controllerAttributes = GetControllerAttributes(controllerToAuthorize, context);
ArrayList actionAttributes = GetMethodAttributes(controllerToAuthorize, actionToAuthorize, context);
if (controllerAttributes.Count == 0 && actionAttributes.Count == 0)
return true;
string roles = "";
string users = "";
if (controllerAttributes.Count > 0)
{
AuthorizeAttribute attribute = controllerAttributes[0] as AuthorizeAttribute;
roles += attribute.Roles;
users += attribute.Users;
}
if (actionAttributes.Count > 0)
{
AuthorizeAttribute attribute = actionAttributes[0] as AuthorizeAttribute;
roles += attribute.Roles;
users += attribute.Users;
}
if (string.IsNullOrEmpty(roles) && string.IsNullOrEmpty(users) && principal.Identity.IsAuthenticated)
return true;
string[] roleArray = roles.Split(',');
string[] usersArray = users.Split(',');
foreach (string role in roleArray)
{
if (role == "*" || principal.IsInRole(role))
return true;
}
foreach (string user in usersArray)
{
if (user == "*" && (principal.Identity.Name == user))
return true;
}
return false;
}
private static Type GetControllerType(string controllerName)
{
Assembly assembly = Assembly.GetExecutingAssembly();
foreach (Type type in assembly.GetTypes())
{
if (
type.BaseType!=null
&& type.BaseType.Name == "Controller"
&& (type.Name.ToUpper() == (controllerName.ToUpper() + "Controller".ToUpper())))
{
return type;
}
}
return null;
}
}
}
[1] http://blog.maartenballiauw.be/post/2008/08/29/Building-an-ASPNET-MVC-sitemap-provider-with-security-trimming.aspxEquivalent to Python's Join method:
/// <summary>
/// same as python 'join'
/// </summary>
/// <typeparam name="T">list type</typeparam>
/// <param name="separator">string separator </param>
/// <param name="list">list of objects to be ToString'd</param>
/// <returns>a concatenated list interleaved with separators</returns>
static public string Join<T>(this string separator, IEnumerable<T> list)
{
var sb = new StringBuilder();
bool first = true;
foreach (T v in list)
{
if (!first)
sb.Append(separator);
first = false;
if (v != null)
sb.Append(v.ToString());
}
return sb.ToString();
}
return string.Join(separator, list.ToArray());
- jpbochi
Convert any string to type Int32
// Calls the underlying int.TryParse method to convert a string
// representation of a number to its 32-bit signed integer equivalent.
// Returns Zero if conversion fails.
public static int ToInt32(this string s)
{
int retInt;
int.TryParse(s, out retInt);
return retInt;
}
SAMPLE USE:
string s = "999";
int i = s.ToInt32();
A generic Try:
class Program
{
static void Main(string[] args)
{
var z = 0;
var a = 0.AsDefaultFor(() => 1 / z);
Console.WriteLine(a);
Console.ReadLine();
}
}
public static class TryExtensions
{
public static T AsDefaultFor<T>(this T @this, Func<T> operation)
{
try
{
return operation();
}
catch
{
return @this;
}
}
}
Put it up on the CodePlex project if you want.
The WhereIf() Method
var query = dc.Reviewer
.Where(r => r.FacilityID == facilityID)
.WhereIf(CheckBoxActive.Checked, r => r.IsActive);
public static IEnumerable<TSource> WhereIf<TSource>(
this IEnumerable<TSource> source,
bool condition, Func<TSource, bool> predicate)
{
if (condition)
return source.Where(predicate);
else
return source;
}
public static IQueryable<TSource> WhereIf<TSource>(
this IQueryable<TSource> source,
bool condition, Expression<Func<TSource, bool>> predicate)
{
if (condition)
return source.Where(predicate);
else
return source;
}
I also added overloads for the index predicate in the Where() extension method. For more fun, add a flavor that includes an additional 'else' predicate.
Inline Conversions: I like this little pattern. Completed it for Boolean, Double and DateTime. Designed to follow the C# is and as operators.
public static Int32? AsInt32(this string s)
{
Int32 value;
if (Int32.TryParse(s, out value))
return value;
return null;
}
public static bool IsInt32(this string s)
{
return s.AsInt32().HasValue;
}
public static Int32 ToInt32(this string s)
{
return Int32.Parse(s);
{
Several times I found myself wanting something like, I think, Groovy's "Safe navigation".
From http://groovy.codehaus.org/Statements:
If you are walking a complex object graph and don't want to have NullPointerExceptions thrown you can use the ?. operator rather than . to perform your navigation.
def foo = null def bar = foo?.something?.myMethod() assert bar == null
So, do you think is a good idea adding an extension method for it? Something like:
obj.SafelyNavigate(x => x.SomeProperty.MaybeAMethod().AnotherProperty);
I think it would be nice even if it can also bring some trouble.
If you think it's a good idea:
Maybe it's just a bad idea :D, but I see it like something that can be useful if done right. If there's nothing like it and you think it holds some value, I may give it a shot and edit the answer afterwards.
I'm always using format that wants a new line with StringBuilder
so the very simple extension below saves a few lines of code:
public static class Extensions
{
public static void AppendLine(this StringBuilder builder,string format, params object[] args)
{
builder.AppendLine(string.Format(format, args));
}
}
The alternative is AppendFormat
in StringBuilder
with a \n
or Environment.NewLine.
A pattern for parsing that avoids out
parameters:
public static bool TryParseInt32(this string input, Action<int> action)
{
int result;
if (Int32.TryParse(input, out result))
{
action(result);
return true;
}
return false;
}
Usage:
if (!textBox.Text.TryParseInt32(number => label.Text = SomeMathFunction(number)))
label.Text = "Please enter a valid integer";
This can be put this in the codeplex project, if so desired
In ASP.NET I always get fed up using FindControl and then having to cast and check if the value is null before referencing. So, I added a TryParse() method to Control [1] that mirrors the similar ones in the framework for Int32 etc.
public static bool TryParse<T>(this Control control, string id, out T result)
where T : Control
{
result = control.FindControl(id) as T;
return result != null;
}
So now you can do this in ASP.NET web-form pages:
Label lbl;
if (Page.TryParse("Label1", out lbl))
{
lbl.Text = "Safely set text";
}
[1] http://msdn.microsoft.com/en-us/library/system.web.ui.control.aspxSome handy string helpers:
Usage:
I hate unwanted spaces trailing or leading strings and since string can take on a null
value, it can be tricky, so i use this:
public bool IsGroup { get { return !this.GroupName.IsNullOrTrimEmpty(); } }
Here is another extention method that i use for a new validation framework [1] i'm trialing. You can see the regex extensions within that help clean otherwise messy regex:
public static bool IsRequiredWithLengthLessThanOrEqualNoSpecial(this String str, int length)
{
return !str.IsNullOrTrimEmpty() &&
str.RegexMatch(
@"^[- \r\n\\\.!:*,@$%&""?\(\)\w']{1,{0}}$".RegexReplace(@"\{0\}", length.ToString()),
RegexOptions.Multiline) == str;
}
Source:
public static class StringHelpers
{
/// <summary>
/// Same as String.IsNullOrEmpty except that
/// it captures the Empty state for whitespace
/// strings by Trimming first.
/// </summary>
public static bool IsNullOrTrimEmpty(this String helper)
{
if (helper == null)
return true;
else
return String.Empty == helper.Trim();
}
public static int TrimLength(this String helper)
{
return helper.Trim().Length;
}
/// <summary>
/// Returns the matched string from the regex pattern. The
/// groupName is for named group match values in the form (?<name>group).
/// </summary>
public static string RegexMatch(this String helper, string pattern, RegexOptions options, string groupName)
{
if (groupName.IsNullOrTrimEmpty())
return Regex.Match(helper, pattern, options).Value;
else
return Regex.Match(helper, pattern, options).Groups[groupName].Value;
}
public static string RegexMatch(this String helper, string pattern)
{
return RegexMatch(helper, pattern, RegexOptions.None, null);
}
public static string RegexMatch(this String helper, string pattern, RegexOptions options)
{
return RegexMatch(helper, pattern, options, null);
}
public static string RegexMatch(this String helper, string pattern, string groupName)
{
return RegexMatch(helper, pattern, RegexOptions.None, groupName);
}
/// <summary>
/// Returns true if there is a match from the regex pattern
/// </summary>
public static bool IsRegexMatch(this String helper, string pattern, RegexOptions options)
{
return helper.RegexMatch(pattern, options).Length > 0;
}
public static bool IsRegexMatch(this String helper, string pattern)
{
return helper.IsRegexMatch(pattern, RegexOptions.None);
}
/// <summary>
/// Returns a string where matching patterns are replaced by the replacement string.
/// </summary>
/// <param name="pattern">The regex pattern for matching the items to be replaced</param>
/// <param name="replacement">The string to replace matching items</param>
/// <returns></returns>
public static string RegexReplace(this String helper, string pattern, string replacement, RegexOptions options)
{
return Regex.Replace(helper, pattern, replacement, options);
}
public static string RegexReplace(this String helper, string pattern, string replacement)
{
return Regex.Replace(helper, pattern, replacement, RegexOptions.None);
}
}
I like to do a lot of regex so i consider these easier than adding the using statement and the extra code to handle named groups.
[1] https://stackoverflow.com/questions/1721327/validate-object-based-on-external-factors-ie-data-store-uniqueness/1741831#1741831For ASP.NET, I use these extensions to HttpSessionState to load objects in session. It allows you to load session objects in a clean manner, and will create and initialize them if they do not exist. I use the two extension methods like so:
private bool CreateMode;
private MyClass SomeClass;
protected override void OnInit (EventArgs e)
{
CreateMode = Session.GetSessionValue<bool> ("someKey1", () => true);
SomeClass = Session.GetSessionClass<MyClass> ("someKey2", () => new MyClass ()
{
MyProperty = 123
});
}
Here are the extension classes:
public static class SessionExtensions
{
public delegate object UponCreate ();
public static T GetSessionClass<T> (this HttpSessionState session,
string key, UponCreate uponCreate) where T : class
{
if (null == session[key])
{
var item = uponCreate () as T;
session[key] = item;
return item;
}
return session[key] as T;
}
public static T GetSessionValue<T> (this HttpSessionState session,
string key, UponCreate uponCreate) where T : struct
{
if (null == session[key])
{
var item = uponCreate();
session[key] = item;
return (T)item;
}
return (T)session[key];
}
}
Hate this kind of code?
CloneableClass cc1 = new CloneableClass ();
CloneableClass cc2 = null;
CloneableClass cc3 = null;
cc3 = (CloneableClass) cc1.Clone (); // this is ok
cc3 = cc2.Clone (); // this throws null ref exception
// code to handle both cases
cc3 = cc1 != null ? (CloneableClass) cc1.Clone () : null;
It's a bit clunky, so I replace it with this extension, which I call CloneOrNull -
public static T CloneOrNull<T> (this T self) where T : class, ICloneable
{
if (self == null) return null;
return (T) self.Clone ();
}
Usage is like:
CloneableClass cc1 = new CloneableClass ();
CloneableClass cc2 = null;
CloneableClass cc3 = null;
cc3 = cc1.CloneOrNull (); // clone of cc1
cc3 = cc2.CloneOrNull (); // null
// look mom, no casts!
Please feel free to use this anywhere!
I use this one all the time:
public static void DelimitedAppend(this StringBuilder sb, string value, string delimiter)
{
if (sb.Length > 0)
sb.Append(delimiter);
sb.Append(value);
}
This just ensures that the delimiter is not inserted when the string is empty. For example, to create a comma-seperated list of words:
var farmAnimals = new[] { new { Species = "Dog", IsTasty = false }, new { Species = "Cat", IsTasty = false }, new { Species = "Chicken", IsTasty = true }, };
var soupIngredients = new StringBuilder();
foreach (var edible in farmAnimals.Where(farmAnimal => farmAnimal.IsTasty))
soupIngredients.DelimitedAppend(edible.Species, ", ");
string.Join(",", strings);
where strings
is an array. This generates roughly 1/3 the IL as the StringBuilder method. - Jim Schubert
A couple of useful extensions if you work with Fiscal Years
/// <summary>
/// Returns the fiscal year for the passed in date
/// </summary>
/// <param name="value">the date</param>
/// <returns>the fiscal year</returns>
public static int FiscalYear(this DateTime value)
{
int ret = value.Year;
if (value.Month >= 7) ret++;
return ret;
}
/// <summary>
/// Returns the fiscal year for the passed in date
/// </summary>
/// <param name="value">the date</param>
/// <returns>the fiscal year</returns>
public static string FiscalYearString(this DateTime value)
{
int fy = FiscalYear(value);
return "{0}/{1}".Format(fy - 1, fy);
}
ASP.NET HTML Encode - short and sweet:
public static string ToHtmlEncodedString(this string s)
{
if (String.IsNullOrEmpty(s))
return s;
return HttpUtility.HtmlEncode(s);
}
Overwrite a portion of a string at a specified index.
I have to work with a system that expects some input values to be fixed width, fixed position strings.
public static string Overwrite(this string s, int startIndex, string newStringValue)
{
return s.Remove(startIndex, newStringValue.Length).Insert(startIndex, newStringValue);
}
So I can do:
string s = new String(' ',60);
s = s.Overwrite(7,"NewValue");
String.Replace
does not modify the source string. - Alex Essilfie
And one more:
public enum ParseFailBehavior
{
ReturnNull,
ReturnDefault,
ThrowException
}
public static T? ParseNullableEnum<T>(this string theValue, ParseFailBehavior desiredBehavior = ParseFailBehavior.ReturnNull) where T:struct
{
T output;
T? result = Enum.TryParse<T>(theValue, out output)
? (T?)output
: desiredBehavior == ParseFailBehavior.ReturnDefault
? (T?)default(T)
: null;
if(result == null && desiredBehavior == ParseFailBehavior.ThrowException)
throw new ArgumentException("Parse Failed for value {0} of enum type {1}".
FormatWith(theValue, typeof(T).Name));
}
This version requires .NET 4.0; in 3.5 you have no TryParse and no optional parameters; you're stuck with Enum.Parse() which you have to try-catch. It's still totally doable in 3.5 (and much more useful as Enum.Parse() is oogly and your only other option):
public static T? ParseNummableEnum<T>(this string theValue)
{
return theValue.ParseNullableEnum<T>(ParseFailBehavior.ReturnNull);
}
public static T? ParseNullableEnum<T>(this string theValue,
ParseFailBehavior desiredBehavior) where T:struct
{
try
{
return (T?) Enum.Parse(typeof (T), theValue);
}
catch (Exception)
{
if(desiredBehavior == ParseFailBehavior.ThrowException) throw;
}
return desiredBehavior == ParseFailBehavior.ReturnDefault ? (T?)default(T) : null;
}
Usage:
//returns null if OptionOne isn't an enum constant
var myEnum = "OptionOne".ParseNullableEnum<OptionEnum>();
//guarantees a return value IF the enum has a "zero" constant value (generally a good practice)
var myEnum = "OptionTwo".ParseNullableEnum<OptionEnum>(ParseFailBehavior.ReturnDefault).Value
Whitespace normalization is rather useful, especially when dealing with user input:
namespace Extensions.String
{
using System.Text.RegularExpressions;
public static class Extensions
{
/// <summary>
/// Normalizes whitespace in a string.
/// Leading/Trailing whitespace is eliminated and
/// all sequences of internal whitespace are reduced to
/// a single SP (ASCII 0x20) character.
/// </summary>
/// <param name="s">The string whose whitespace is to be normalized</param>
/// <returns>a normalized string</returns>
public static string NormalizeWS( this string @this )
{
string src = @this ?? "" ;
string normalized = rxWS.Replace( src , m =>{
bool isLeadingTrailingWS = ( m.Index == 0 || m.Index+m.Length == src.Length ? true : false ) ;
string p = ( isLeadingTrailingWS ? "" : " " ) ;
return p ;
}) ;
return normalized ;
}
private static Regex rxWS = new Regex( @"\s+" ) ;
}
}
Some tools to IEnumerable: ToString(Format), ToString(Function) and Join(Separator).
For example:
var names = new[] { "Wagner", "Francine", "Arthur", "Bernardo" };
names.ToString("Name: {0}\n");
// Name: Wagner
// Name: Francine
// Name: Arthur
// Name: Bernardo
names.ToString(name => name.Length > 6 ? String.Format("{0} ", name) : String.Empty);
// Francine Bernardo
names.Join(" - ");
// Wagner - Francine - Arthur - Bernardo
Extensions:
public static string ToString<T>(this IEnumerable<T> self, string format)
{
return self.ToString(i => String.Format(format, i));
}
public static string ToString<T>(this IEnumerable<T> self, Func<T, object> function)
{
var result = new StringBuilder();
foreach (var item in self) result.Append(function(item));
return result.ToString();
}
public static string Join<T>(this IEnumerable<T> self, string separator)
{
return String.Join(separator, values: self.ToArray());
}
Join<T>
method with this: return string.Join(seperator, self.ToArray())
. - Pondidum
Use reflection to find the TryParse method and invoke it upon string target. The optional parameter specifies what should be returned if the conversion fails. I find this method quite useful, most of the time. Well aware of the Convert.ChangeType
option, but I find this more useful what with the default result handy and whatnot. Note that the found methods are kept in a dictionary, although I do suspect that boxing ultimately slows this down a bit.
This method is my favorite, because it legitimately uses a lot of language features.
private static readonly Dictionary<Type, MethodInfo> Parsers = new Dictionary<Type, MethodInfo>();
public static T Parse<T>(this string value, T defaultValue = default(T))
{
if (string.IsNullOrEmpty(value)) return defaultValue;
if (!Parsers.ContainsKey(typeof(T)))
Parsers[typeof (T)] = typeof (T).GetMethods(BindingFlags.Public | BindingFlags.Static)
.Where(mi => mi.Name == "TryParse")
.Single(mi =>
{
var parameters = mi.GetParameters();
if (parameters.Length != 2) return false;
return parameters[0].ParameterType == typeof (string) &&
parameters[1].ParameterType == typeof (T).MakeByRefType();
});
var @params = new object[] {value, default(T)};
return (bool) Parsers[typeof (T)].Invoke(null, @params) ?
(T) @params[1] : defaultValue;
}
Usage:
var hundredTwentyThree = "123".Parse(0);
var badnumber = "test".Parse(-1);
var date = "01/01/01".Parse<DateTime>();
There is somethimes need to have instance of class no matter if valid but not null
public static T Safe<T>(this T obj) where T : new()
{
if (obj == null)
{
obj = new T();
}
return obj;
}
usage will be like:
MyClass myClass = Provider.GetSomeResult();
string temp = myClass.Safe().SomeValue;
instead of:
MyClass myClass = Provider.GetSomeResult();
string temp = "some default value";
if (myClass != null)
{
temp = myClass.SomeValue;
}
sorry if it is a duplicity, but I dont find it.
I haven't seen any answer with this one yet...
public static string[] Split(this string value, string regexPattern)
{
return value.Split(regexPattern, RegexOptions.None);
}
public static string[] Split(this string value, string regexPattern,
RegexOptions options)
{
return Regex.Split(value, regexPattern, options);
}
Usage:
var obj = "test1,test2,test3";
string[] arrays = obj.Split(",");
For adding multiple elements to a collection that doesn't have AddRange, e.g., collection.Add(item1, item2, itemN);
static void Add<T>(this ICollection<T> coll, params T[] items)
{ foreach (var item in items) coll.Add(item);
}
The following is like string.Format()
but with custom string representation of arguments, e.g., "{0} {1} {2}".Format<Custom>(c=>c.Name,"string",new object(),new Custom())
results in "string {System.Object} Custom1Name"
static string Format<T>( this string format
, Func<T,object> select
, params object[] args)
{ for(int i=0; i < args.Length; ++i)
{ var x = args[i] as T;
if (x != null) args[i] = select(x);
}
return string.Format(format, args);
}
// Values ordered true/false
// True/false values separated by a capital letter
// Only two values allowed
// ---------------------------
// Limited, but could be useful
public enum BooleanFormat
{
OneZero,
YN,
YesNo,
TF,
TrueFalse,
PassFail,
YepNope
}
public static class BooleanExtension
{
/// <summary>
/// Converts the boolean value of this instance to the specified string value.
/// </summary>
private static string ToString(this bool value, string passValue, string failValue)
{
return value ? passValue : failValue;
}
/// <summary>
/// Converts the boolean value of this instance to a string.
/// </summary>
/// <param name="booleanFormat">A BooleanFormat value.
/// Example: BooleanFormat.PassFail would return "Pass" if true and "Fail" if false.</param>
/// <returns>Boolean formatted string</returns>
public static string ToString(this bool value, BooleanFormat booleanFormat)
{
string booleanFormatString = Enum.GetName(booleanFormat.GetType(), booleanFormat);
return ParseBooleanString(value, booleanFormatString);
}
// Parses boolean format strings, not optimized
private static string ParseBooleanString(bool value, string booleanFormatString)
{
StringBuilder trueString = new StringBuilder();
StringBuilder falseString = new StringBuilder();
int charCount = booleanFormatString.Length;
bool isTrueString = true;
for (int i = 0; i != charCount; i++)
{
if (char.IsUpper(booleanFormatString[i]) && i != 0)
isTrueString = false;
if (isTrueString)
trueString.Append(booleanFormatString[i]);
else
falseString.Append(booleanFormatString[i]);
}
return (value == true ? trueString.ToString() : falseString.ToString());
}
Perhaps the most useful extension methods I've written and used are here:
http://www.codeproject.com/KB/cs/fun-with-cs-extensions.aspx?msg=2838918#xx2838918xx
// Checks for an empty collection, and sends the value set in the default constructor for the desired field
public static TResult MinGuarded<T, TResult>(this IEnumerable<T> items, Func<T, TResult> expression) where T : new() {
if(items.IsEmpty()) {
return (new List<T> { new T() }).Min(expression);
}
return items.Min(expression);
}
// Checks for an empty collection, and sends the value set in the default constructor for the desired field
public static TResult MaxGuarded<T, TResult>(this IEnumerable<T> items, Func<T, TResult> expression) where T : new() {
if(items.IsEmpty()) {
return (new List<T> { new T() }).Max(expression);
}
return items.Max(expression);
}
I am not sure if there is a better way to do this, but this extension is very helpful whenever I want to have control over the default values of fields in my object.
For instance, if I want to control the value of a DateTime and want to be set as per my business logic, then I can do so in the default constructor. Otherwise, it comes out to be DateTime.MinDate
.
Aww why not! Here's an extension to IList (can't be IEnumerable because i use list specific features) for insertion sort.
internal static class SortingHelpers
{
/// <summary>
/// Performs an insertion sort on this list.
/// </summary>
/// <typeparam name="T">The type of the list supplied.</typeparam>
/// <param name="list">the list to sort.</param>
/// <param name="comparison">the method for comparison of two elements.</param>
/// <returns></returns>
public static void InsertionSort<T>(this IList<T> list, Comparison<T> comparison)
{
for (int i = 2; i < list.Count; i++)
{
for (int j = i; j > 1 && comparison(list[j], list[j - 1]) < 0; j--)
{
T tempItem = list[j];
list.RemoveAt(j);
list.Insert(j - 1, tempItem);
}
}
}
}
An example:
List<int> list1 = { 3, 5, 1, 2, 9, 4, 6 };
list1.InsertionSort((a,b) => a - b);
//list is now in order of 1,2,3,4,5,6,9
IComparer<T>
or Comparison<T>
(or an overload for each), instead of a "less" function, which smacks of STL. - P Daddy
Comparison<T>
is equivalent to Func<T, T, int>
, which is the same interface as IComparer<T>.Compare
. This is the standard comparer interface that .NET developers are used to. Most sorting functions only need to compare less than or greater than. You've chosen less than. If you look in Reflector at Array.SorterGenericArray.QuickSort()
(or Array.SorterObjectArray.QuickSort()
), you'll see that Array.Sort
also only uses less than, but it does it with comparer.Compare(a, b) < 0
, keeping with the established interface for the platform. - P Daddy
IComparer<T>
also allows your users (or you) to use Comparer<T>.Default
instead of implementing the comparison by hand. The best interface when a comparison is involved usually has three overloads, one taking IComparer<T>
, one taking Comparison<T>
, and one taking no comparer and assuming Comparer<T>.Default
. - P Daddy
In the recent searches section on my blog stats page, I had removed all duplicates, but needed a way to remove nearly-duplicate lines. I'd get tons of similar but not quite the same Google queries.
I ended up using an anonymous type instead of a dictionary, but wanted a way to create a List of that anonymous type. You can't do that, but you can create a List<dynamic>
in .NET 4.0 :)
Mostly I like it because I effectively get a List<AnonymousType#1>()
.
/// <summary>Remove extraneous entries for common word permutations</summary>
/// <param name="input">Incoming series of words to be filtered</param>
/// <param name="MaxIgnoreLength">Words this long or shorter will not count as duplicates</param>
/// <param name="words2">Instance list from BuildInstanceList()</param>
/// <returns>Filtered list of lines from input, based on filter info in words2</returns>
private static List<string> FilterNearDuplicates(List<string> input, int MaxIgnoreLength, List<dynamic> words2)
{
List<string> output = new List<string>();
foreach (string line in input)
{
int Dupes = 0;
foreach (string word in line.Split(new char[] { ' ', ',', ';', '\\', '/', ':', '\"', '\r', '\n', '.' })
.Where(p => p.Length > MaxIgnoreLength)
.Distinct())
{
int Instances = 0;
foreach (dynamic dyn in words2)
if (word == dyn.Word)
{
Instances = dyn.Instances;
if (Instances > 1)
Dupes++;
break;
}
}
if (Dupes == 0)
output.Add(line);
}
return output;
}
/// <summary>Builds a list of words and how many times they occur in the overall list</summary>
/// <param name="input">Incoming series of words to be counted</param>
/// <returns></returns>
private static List<dynamic> BuildInstanceList(List<string> input)
{
List<dynamic> words2 = new List<object>();
foreach (string line in input)
foreach (string word in line.Split(new char[] { ' ', ',', ';', '\\', '/', ':', '\"', '\r', '\n', '.' }))
{
if (string.IsNullOrEmpty(word))
continue;
else if (ExistsInList(word, words2))
for (int i = words2.Count - 1; i >= 0; i--)
{
if (words2[i].Word == word)
words2[i] = new { Word = words2[i].Word, Instances = words2[i].Instances + 1 };
}
else
words2.Add(new { Word = word, Instances = 1 });
}
return words2;
}
/// <summary>Determines whether a dynamic Word object exists in a List of this dynamic type.</summary>
/// <param name="word">Word to look for</param>
/// <param name="words">Word dynamics to search through</param>
/// <returns>Indicator of whether the word exists in the list of words</returns>
private static bool ExistsInList(string word, List<dynamic> words)
{
foreach (dynamic dyn in words)
if (dyn.Word == word)
return true;
return false;
}
Some DataSet/DataRow extensions to make working with db results a little simpler
Just use .Field("fieldname") on the DataRow and it will cast it if it can, optional default can be included.
Also .HasRows() on the DataSet so you don't need to check for the existence of a table and rows.
Example:
using (DataSet ds = yourcall())
{
if (ds.HasRows())
{
foreach (DataRow dr in ds.Tables[0].Rows)
{
int id = dr.Field<int>("ID");
string name = dr.Field<string>("Name");
string Action = dr.Field<string>("Action", "N/A");
}
}
}
Code:
using System;
using System.Data;
public static class DataSetExtensions
{
public static T Field<T>(this DataRow row, string columnName, T defaultValue)
{
try
{
return row.Field<T>(columnName);
}
catch
{
return defaultValue;
}
}
public static T Field<T>(this DataRow row, string columnName)
{
if (row[columnName] == null)
throw new NullReferenceException(columnName + " does not exist in DataRow");
string value = row[columnName].ToString();
if (typeof(T) == "".GetType())
{
return (T)Convert.ChangeType(value, typeof(T));
}
else if (typeof(T) == 0.GetType())
{
return (T)Convert.ChangeType(int.Parse(value), typeof(T));
}
else if (typeof(T) == false.GetType())
{
return (T)Convert.ChangeType(bool.Parse(value), typeof(T));
}
else if (typeof(T) == DateTime.Now.GetType())
{
return (T)Convert.ChangeType(DateTime.Parse(value), typeof(T));
}
else if (typeof(T) == new byte().GetType())
{
return (T)Convert.ChangeType(byte.Parse(value), typeof(T));
}
else if (typeof(T) == new float().GetType())
{
return (T)Convert.ChangeType(float.Parse(value), typeof(T));
}
else
{
throw new ArgumentException(string.Format("Cannot cast '{0}' to '{1}'.", value, typeof(T).ToString()));
}
}
public static bool HasRows(this DataSet dataSet)
{
return (dataSet.Tables.Count > 0 && dataSet.Tables[0].Rows.Count > 0);
}
}
public static class StringHelper
{
public static String F(this String str, params object[] args)
{
return String.Format(str, args);
}
}
Using like:
"Say {0}".F("Hello");
public static class DictionaryExtensions
{
public static Nullable<TValue> GetValueOrNull<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, TKey key)
where TValue : struct
{
TValue result;
if (dictionary.TryGetValue(key, out result))
return result;
else
return null;
}
}
Free to use, just mention my name (Janko Röbisch) in the code.
// This file contains extension methods for generic List<> class to operate on sorted lists.
// Duplicate values are OK.
// O(ln(n)) is still much faster then the O(n) of LINQ's searches/filters.
static partial class SortedList
{
// Return the index of the first element with the key greater then provided.
// If there's no such element within the provided range, it returns iAfterLast.
public static int sortedFirstGreaterIndex<tElt, tKey>( this IList<tElt> list, Func<tElt, tKey, int> comparer, tKey key, int iFirst, int iAfterLast )
{
if( iFirst < 0 || iAfterLast < 0 || iFirst > list.Count || iAfterLast > list.Count )
throw new IndexOutOfRangeException();
if( iFirst > iAfterLast )
throw new ArgumentException();
if( iFirst == iAfterLast )
return iAfterLast;
int low = iFirst, high = iAfterLast;
// The code below is inspired by the following article:
// http://en.wikipedia.org/wiki/Binary_search#Single_comparison_per_iteration
while( low < high )
{
int mid = ( high + low ) / 2;
// 'mid' might be 'iFirst' in case 'iFirst+1 == iAfterLast'.
// 'mid' will never be 'iAfterLast'.
if( comparer( list[ mid ], key ) <= 0 ) // "<=" since we gonna find the first "greater" element
low = mid + 1;
else
high = mid;
}
return low;
}
// Return the index of the first element with the key greater then the provided key.
// If there's no such element, returns list.Count.
public static int sortedFirstGreaterIndex<tElt, tKey>( this IList<tElt> list, Func<tElt, tKey, int> comparer, tKey key )
{
return list.sortedFirstGreaterIndex( comparer, key, 0, list.Count );
}
// Add an element to the sorted array.
// This could be an expensive operation if frequently adding elements that sort firstly.
// This is cheap operation when adding elements that sort near the tail of the list.
public static int sortedAdd<tElt>( this List<tElt> list, Func<tElt, tElt, int> comparer, tElt elt )
{
if( list.Count == 0 || comparer( list[ list.Count - 1 ], elt ) <= 0 )
{
// either the list is empty, or the item is greater then all elements already in the collection.
list.Add( elt );
return list.Count - 1;
}
int ind = list.sortedFirstGreaterIndex( comparer, elt );
list.Insert( ind, elt );
return ind;
}
// Find first exactly equal element, return -1 if not found.
public static int sortedFindFirstIndex<tElt, tKey>( this List<tElt> list, Func<tElt, tKey, int> comparer, tKey elt )
{
int low = 0, high = list.Count - 1;
while( low < high )
{
int mid = ( high + low ) / 2;
if( comparer( list[ mid ], elt ) < 0 )
low = mid + 1;
else
high = mid; // this includes the case when we've found an element exactly matching the key
}
if( high >= 0 && 0 == comparer( list[ high ], elt ) )
return high;
return -1;
}
// Return the IEnumerable that returns array elements in the reverse order.
public static IEnumerable<tElt> sortedReverse<tElt>( this List<tElt> list )
{
for( int i=list.Count - 1; i >= 0; i-- )
yield return list[ i ];
}
}
This one is not fully baked as we just came up with it this morning. It will generate a full class definition for a Type. Useful for situations where you have a a large class and want to create a subset or full definition but don't have access to it. For example, to store the object in a database etc.
public static class TypeExtensions
{
public static string GenerateClassDefinition(this Type type)
{
var properties = type.GetFields();
var sb = new StringBuilder();
var classtext = @"private class $name
{
$props}";
foreach (var p in GetTypeInfo(type))
{
sb.AppendFormat(" public {0} {1} ", p.Item2, p.Item1).AppendLine(" { get; set; }");
}
return classtext.Replace("$name", type.Name).Replace("$props", sb.ToString());
}
#region Private Methods
private static List<Tuple<string, string>> GetTypeInfo(Type type)
{
var ret = new List<Tuple<string, string>>();
var fields = type.GetFields();
var props = type.GetProperties();
foreach(var p in props) ret.Add(new Tuple<string, string>(p.Name, TranslateType(p.PropertyType)));
foreach(var f in fields) ret.Add(new Tuple<string, string>(f.Name, TranslateType(f.FieldType)));
return ret;
}
private static string TranslateType(Type input)
{
string ret;
if (Nullable.GetUnderlyingType(input) != null)
{
ret = string.Format("{0}?", TranslateType(Nullable.GetUnderlyingType(input)));
}
else
{
switch (input.Name)
{
case "Int32": ret = "int"; break;
case "Int64": ret = "long"; break;
case "IntPtr": ret = "long"; break;
case "Boolean": ret = "bool"; break;
case "String":
case "Char":
case "Decimal":
ret = input.Name.ToLower(); break;
default: ret = input.Name; break;
}
}
return ret;
}
#endregion
}
Example usage:
Process.GetProcesses().First().GetType().GenerateClassDefinition();
Becomes even more handy if using linqpad:
Process.GetProcesses().First().GetType().GenerateClassDefinition().Dump();
AppendFormat
method which uses index formatters just like String.Format
. You shouldn't be calling Replace on String template place holders like that anyway. You're implicit-typing string. The only reason to convert a struct.Name
to the alias is readability, even then it doesn't make much sense. And, IntPtr
is platform-specfic so this code only works on 64-bit. The code generated by this won't reflect the actual code you're trying to generate. - Jim Schubert
Should a private class not have any accessors with more visibility than private?
No. Unless this class is a nested class, which your code doesn't suggest, you'll get the error Elements defined in a namespace cannot be explicitly declared as private, protected, or protected internal
. I can understand quickly generating classes to match db, I do it myself. Also, StringBuilder has AppendFormat()
and AppendLine();
Just call them both or write an extension method called AppendFormatLine. - Jim Schubert
var
keyword causes the compiler to determine that variable's type. When you know it's a string, why not call it a string so the compiler doesn't have to do anything extra? The comment about the struct.Name
getting converted to an alias means you are taking the actual struct from the BCL (e.g. Int32) and renaming it in a string using it's alias (e.g. int). There's nothing really wrong with this, but you can just as easily call an int "Int32" or a long "Int64" or an IntPtr "IntPtr". In changing the name to the alias, you've introduced that 64-bit bug. - Jim Schubert
internal
. My point is that I don't understand why you're "forcing the developer" to do something by generating code that will not compile... why not leave off the access modifier? Isn't that the convention used when Visual Studio generates a class stub for you? By using the private variable, you're inevitably going to cause confusion. - Jim Schubert
Smalltalk style if/else in c#. [1]
Feel free to put this on codeplex under whatever license you are using
using System;
namespace SmalltalkBooleanExtensionMethods
{
public static class BooleanExtension
{
public static T ifTrue<T> (this bool aBoolean, Func<T> method)
{
if (aBoolean)
return (T)method();
else
return default(T);
}
public static void ifTrue (this bool aBoolean, Action method)
{
if (aBoolean)
method();
}
public static T ifFalse<T> (this bool aBoolean, Func<T> method)
{
if (!aBoolean)
return (T)method();
else
return default(T);
}
public static void ifFalse (this bool aBoolean, Action method)
{
if (!aBoolean)
method();
}
public static T ifTrueifFalse<T> (this Boolean aBoolean, Func<T> methodA, Func<T> methodB)
{
if (aBoolean)
return (T)methodA();
else
return (T)methodB();
}
public static void ifTrueifFalse (this Boolean aBoolean, Action methodA, Action methodB)
{
if (aBoolean)
methodA();
else
methodB();
}
}
}
You probably already have a timesRepeat method but its in there.
using System;
namespace SmalltalkBooleanExtensionMethods
{
public static class IntExtension
{
public static int timesRepeat<T>(this int x, Func<T> method)
{
for (int i = x; i > 0; i--)
{
method();
}
return x;
}
public static int timesRepeat(this int x, Action method)
{
for (int i = x; i > 0; i--)
{
method();
}
return x;
}
}
}
Nunit Tests
using System;
using SmalltalkBooleanExtensionMethods;
using NUnit.Framework;
namespace SmalltalkBooleanExtensionMethodsTest
{
[TestFixture]
public class SBEMTest
{
int i;
bool itWorks;
[SetUp]
public void Init()
{
i = 0;
itWorks = false;
}
[Test()]
public void TestifTrue()
{
itWorks = (true.ifTrue(() => true));
Assert.IsTrue(itWorks);
}
[Test()]
public void TestifFalse()
{
itWorks = (false.ifFalse(() => true));
Assert.IsTrue(itWorks);
}
[Test()]
public void TestifTrueifFalse()
{
itWorks = false.ifTrueifFalse(() => false, () => true);
Assert.IsTrue(itWorks);
itWorks = false;
itWorks = true.ifTrueifFalse(() => true, () => false);
Assert.IsTrue(itWorks);
}
[Test()]
public void TestTimesRepeat()
{
(5).timesRepeat(() => i = i + 1);
Assert.AreEqual(i, 5);
}
[Test()]
public void TestVoidMethodIfTrue()
{
true.ifTrue(() => SetItWorksBooleanToTrue());
Assert.IsTrue(itWorks);
}
[Test()]
public void TestVoidMethodIfFalse()
{
false.ifFalse(() => SetItWorksBooleanToTrue());
Assert.IsTrue(itWorks);
}
public void TestVoidMethodIfTrueIfFalse()
{
true.ifTrueifFalse(() => SetItWorksBooleanToTrue(), () => SetItWorksBooleanToFalse());
false.ifTrueifFalse(() => SetItWorksBooleanToFalse(), () => SetItWorksBooleanToTrue());
Assert.IsTrue(itWorks);
}
public void TestVoidMethodTimesRepeat()
{
(5).timesRepeat(() => AddOneToi());
Assert.AreEqual(i, 5);
}
public void SetItWorksBooleanToTrue()
{
itWorks = true;
}
public void SetItWorksBooleanToFalse()
{
itWorks = false;
}
public void AddOneToi()
{
i = i + 1;
}
}
}
[1] https://github.com/rtaycher/Smalltalk-like-control-structures/blob/master/SmalltalkBooleanExtensionMethods/BooleanExtension.csmethod.DynamicInvoke()
? A direct call like this: method()
is much faster. stackoverflow.com/questions/932699/… - Greg
Ive created a extension method to select an item in a dropdown in ASP.NET.
Below is the code
public static class Utilities
{
public enum DropDownListSelectionType
{
ByValue,
ByText
}
public static void SelectItem(this System.Web.UI.WebControls.DropDownList drp, string selectedValue, DropDownListSelectionType type)
{
drp.ClearSelection();
System.Web.UI.WebControls.ListItem li;
if (type == DropDownListSelectionType.ByValue)
li = drp.Items.FindByValue(selectedValue.Trim());
else
li = drp.Items.FindByText(selectedValue.Trim());
if (li != null)
li.Selected = true;
}}
This method can be called by the following lines of code to either select by text
DropDownList1.SelectItem("ABCD", Utilities.DropDownListSelectionType.ByText);
or select by value
DropDownList1.SelectItem("11", Utilities.DropDownListSelectionType.ByValue);
The above code doesnt select anything if it cant find the text/value passed in.
And here's the control-invoke extension i'm using regularly;
public static class InvokeExtensions
{
public static void InvokeHandler(this Control control, MethodInvoker del) // Sync. control-invoke extension.
{
if (control.InvokeRequired)
{
control.Invoke(del);
return;
}
del(); // run the actual code.
}
public static void AsyncInvokeHandler(this Control control, MethodInvoker del) // Async. control-invoke extension.
{
if (control.InvokeRequired)
{
control.BeginInvoke(del);
return;
}
del(); // run the actual code.
}
}
sample;
this.TreeView.AsyncInvokeHandler(() =>
{
this.Text = 'xyz'
});
which allows cross-thread gui-updates.
Compare the equality of two objects without (necessarily) overriding Equals or implementing IEquatable<>.
Why would you want to do this? When you really want to know if two objects are equal, but you're too lazy to override Equals(object)
or implement IEquatable<T>
. Or, more realistically, if you have a terribly complex class and implementing Equals by hand would be extremely tedious, error prone, and not fun to maintain. It also helps if you don't care too much about performance.
I am currently using IsEqualTo
because of the second reason - I have a class with many properties whose types are other user-defined classes, each of which has many other properties whose types are other user-defined classes, ad infinitum. Throw in a bunch of collections in many of these classes, and implementing Equals(object)
truly becomes a nightmare.
Usage:
if (myTerriblyComplexObject.IsEqualTo(myOtherTerriblyComplexObject))
{
// Do something terribly interesting.
}
In order to determine equality, I make numerous comparisons. I make every attempt to do the "right" one in the "right" order. The comparisons, in order are:
Equals(object, object)
method. If it returns true, return true. It will return true if the references are the same. It will also return true if thisObject
overrides Equals(object)
.thisObject
is null, return false. No further comparisons can be made if it is null.thisObject
has overridden Equals(object)
, return false. Since it overrides Equals, it must mean that Equals was executed at step #1 and returned false. If someone has bothered to override Equals, we should respect that and return what Equals returns.thisObject
inherits from IEquatable<T>
, where otherObject
can be assigned to T
, get the Equals(T)
method using reflection. Invoke that method and return its return value.IEnumerable
, return whether contain the same items, in the same order, using IsEqualTo to compare the items.thisObject
does not have an Equals method, there isn't any way to realistically evaluate two object of different types to be true.Equals(object)
test - enough said.thisObject
, test its value with IsEqualTo. If any return false, return false. If all return true, return true.String comparisons could be better, but easy to implement. Also, I'm not 100% sure I'm handling structs right.
Without further ado, here is the extension method:
/// <summary>
/// Provides extension methods to determine if objects are equal.
/// </summary>
public static class EqualsEx
{
/// <summary>
/// The <see cref="Type"/> of <see cref="string"/>.
/// </summary>
private static readonly Type StringType = typeof(string);
/// <summary>
/// The <see cref="Type"/> of <see cref="object"/>.
/// </summary>
private static readonly Type ObjectType = typeof(object);
/// <summary>
/// The <see cref="Type"/> of <see cref="IEquatable{T}"/>.
/// </summary>
private static readonly Type EquatableType = typeof(IEquatable<>);
/// <summary>
/// Determines whether <paramref name="thisObject"/> is equal to <paramref name="otherObject"/>.
/// </summary>
/// <param name="thisObject">
/// This object.
/// </param>
/// <param name="otherObject">
/// The other object.
/// </param>
/// <returns>
/// True, if they are equal, otherwise false.
/// </returns>
public static bool IsEqualTo(this object thisObject, object otherObject)
{
if (Equals(thisObject, otherObject))
{
// Always check Equals first. If the object has overridden Equals, use it. This will also capture the case where both are the same reference.
return true;
}
if (thisObject == null)
{
// Because Equals(object, object) returns true if both are null, if either is null, return false.
return false;
}
var thisObjectType = thisObject.GetType();
var equalsMethod = thisObjectType.GetMethod("Equals", BindingFlags.Public | BindingFlags.Instance, null, new[] { ObjectType }, null);
if (equalsMethod.DeclaringType == thisObjectType)
{
// thisObject overrides Equals, and we have already failed the Equals test, so return false.
return false;
}
var otherObjectType = otherObject == null ? null : otherObject.GetType();
// If thisObject inherits from IEquatable<>, and otherObject can be passed into its Equals method, use it.
var equatableTypes = thisObjectType.GetInterfaces().Where( // Get interfaces of thisObjectType that...
i => i.IsGenericType // ...are generic...
&& i.GetGenericTypeDefinition() == EquatableType // ...and are IEquatable of some type...
&& (otherObjectType == null || i.GetGenericArguments()[0].IsAssignableFrom(otherObjectType))); // ...and otherObjectType can be assigned to the IEquatable's type.
if (equatableTypes.Any())
{
// If we found any interfaces that meed our criteria, invoke the Equals method for each interface.
// If any return true, return true. If all return false, return false.
return equatableTypes
.Select(equatableType => equatableType.GetMethod("Equals", BindingFlags.Public | BindingFlags.Instance))
.Any(equatableEqualsMethod => (bool)equatableEqualsMethod.Invoke(thisObject, new[] { otherObject }));
}
if (thisObjectType != StringType && thisObject is IEnumerable && otherObject is IEnumerable)
{
// If both are IEnumerable, check their items.
var thisEnumerable = ((IEnumerable)thisObject).Cast<object>();
var otherEnumerable = ((IEnumerable)otherObject).Cast<object>();
return thisEnumerable.SequenceEqual(otherEnumerable, IsEqualToComparer.Instance);
}
if (thisObjectType != otherObjectType)
{
// If they have different types, they cannot be equal.
return false;
}
if (thisObjectType.IsValueType || thisObjectType == StringType)
{
// If it is a value type, we have already determined that they are not equal, so return false.
return false;
}
// Recurse into each public property: if any are not equal, return false. If all are true, return true.
return !(from propertyInfo in thisObjectType.GetProperties()
let thisPropertyValue = propertyInfo.GetValue(thisObject, null)
let otherPropertyValue = propertyInfo.GetValue(otherObject, null)
where !thisPropertyValue.IsEqualTo(otherPropertyValue)
select thisPropertyValue).Any();
}
/// <summary>
/// A <see cref="IEqualityComparer{T}"/> to be used when comparing sequences of collections.
/// </summary>
private class IsEqualToComparer : IEqualityComparer<object>
{
/// <summary>
/// The singleton instance of <see cref="IsEqualToComparer"/>.
/// </summary>
public static readonly IsEqualToComparer Instance;
/// <summary>
/// Initializes static members of the <see cref="EqualsEx.IsEqualToComparer"/> class.
/// </summary>
static IsEqualToComparer()
{
Instance = new IsEqualToComparer();
}
/// <summary>
/// Prevents a default instance of the <see cref="EqualsEx.IsEqualToComparer"/> class from being created.
/// </summary>
private IsEqualToComparer()
{
}
/// <summary>
/// Determines whether the specified objects are equal.
/// </summary>
/// <param name="x">
/// The first object to compare.
/// </param>
/// <param name="y">
/// The second object to compare.
/// </param>
/// <returns>
/// true if the specified objects are equal; otherwise, false.
/// </returns>
bool IEqualityComparer<object>.Equals(object x, object y)
{
return x.IsEqualTo(y);
}
/// <summary>
/// Not implemented - throws an <see cref="NotImplementedException"/>.
/// </summary>
/// <param name="obj">
/// The <see cref="object"/> for which a hash code is to be returned.
/// </param>
/// <returns>
/// A hash code for the specified object.
/// </returns>
int IEqualityComparer<object>.GetHashCode(object obj)
{
throw new NotImplementedException();
}
}
}
Sql server has a limit of ~2000 parameters, which is a pain if you have 10k Ids and want the records connected with them. I wrote these methods which accept batched lists of ids and are called like this:
List<Order> orders = dataContext.Orders.FetchByIds(
orderIdChunks,
list => row => list.Contains(row.OrderId)
);
List<Customer> customers = dataContext.Orders.FetchByIds(
orderIdChunks,
list => row => list.Contains(row.OrderId),
row => row.Customer
);
public static List<ResultType> FetchByIds<RecordType, ResultType>(
this IQueryable<RecordType> querySource,
List<List<int>> IdChunks,
Func<List<int>, Expression<Func<RecordType, bool>>> filterExpressionGenerator,
Expression<Func<RecordType, ResultType>> projectionExpression
) where RecordType : class
{
List<ResultType> result = new List<ResultType>();
foreach (List<int> chunk in IdChunks)
{
Expression<Func<RecordType, bool>> filterExpression =
filterExpressionGenerator(chunk);
IQueryable<ResultType> query = querySource
.Where(filterExpression)
.Select(projectionExpression);
List<ResultType> rows = query.ToList();
result.AddRange(rows);
}
return result;
}
public static List<RecordType> FetchByIds<RecordType>(
this IQueryable<RecordType> querySource,
List<List<int>> IdChunks,
Func<List<int>, Expression<Func<RecordType, bool>>> filterExpressionGenerator
) where RecordType : class
{
Expression<Func<RecordType, RecordType>> identity = r => r;
return FetchByIds(
querySource,
IdChunks,
filterExpressionGenerator,
identity
);
}
We have a deployment tool to deploy between environments. Since the files could be marked as modified but not actually different I came up with this:
/// <summary>
/// Compares the files to see if they are different.
/// First checks file size
/// Then modified if the file is larger than the specified size
/// Then compares the bytes
/// </summary>
/// <param name="file1">The source file</param>
/// <param name="file2">The destination file</param>
/// <param name="mb">Skip the smart check if the file is larger than this many megabytes. Default is 10.</param>
/// <returns></returns>
public static bool IsDifferentThan(this FileInfo file1, FileInfo file2, int mb = 10)
{
var ret = false;
// different size is a different file
if(file1.Length != file2.Length) return true;
// if the file times are different and the file is bigger than 10mb flag it for updating
if(file1.LastWriteTimeUtc > file2.LastWriteTimeUtc && file1.Length > ((mb*1024)*1024)) return true;
var f1 = File.ReadAllBytes(file1.FullName);
var f2 = File.ReadAllBytes(file2.FullName);
// loop through backwards because if they are different
// it is more likely that the last few bytes will be different
// than the first few
for(var i = file1.Length - 1; i > 0; i--)
{
if(f1[i] != f2[i])
{
ret = true;
break;
}
}
return ret;
}
If you have persian language and must show the numbers to users in persian language:
static public string ToFaString (this string value)
{
// 1728 , 1584
string result = "";
if (value != null)
{
char[] resChar = value.ToCharArray();
for (int i = 0; i < resChar.Length; i++)
{
if (resChar[i] >= '0' && resChar[i] <= '9')
result += (char)(resChar[i] + 1728);
else
result += resChar[i];
}
}
return result;
}
If you need for check your string for Is All char is 0 :
static public bool IsAllZero (this string input)
{
if(string.IsNullOrEmpty(input))
return true;
foreach (char ch in input)
{
if(ch != '0')
return false;
}
return true;
}
myString.All(c => c == '0')
if you want to keep the same meaning... - Thomas Levesque
on serializing and configs there is better using long as DateTime, so:
public static readonly DateTime Epoch = new DateTime(1970, 1, 1, 0, 0, 0);
public static long ToUnixTimestamp(this DateTime dateTime)
{
return (long) (dateTime - Epoch).TotalSeconds;
}
public static long ToUnixUltraTimestamp(this DateTime dateTime)
{
return (long) (dateTime - Epoch).TotalMilliseconds;
}
and backwards
public static DateTime ToDateTime(this long unixDateTime)
{
return Epoch.AddSeconds(unixDateTime);
}
public static DateTime ToDateTimeUltra(this long unixUltraDateTime)
{
return Epoch.AddMilliseconds(unixUltraDateTime);
}
I use the following extensions to extend all collections (maybe someone find these useful):
/// <summary>
/// Collection Helper
/// </summary>
/// <remarks>
/// Use IEnumerable by default, but when altering or getting item at index use IList.
/// </remarks>
public static class CollectionHelper
{
#region Alter;
/// <summary>
/// Swap item to another place
/// </summary>
/// <typeparam name="T">Collection type</typeparam>
/// <param name="this">Collection</param>
/// <param name="IndexA">Index a</param>
/// <param name="IndexB">Index b</param>
/// <returns>New collection</returns>
public static IList<T> Swap<T>(this IList<T> @this, Int32 IndexA, Int32 IndexB)
{
T Temp = @this[IndexA];
@this[IndexA] = @this[IndexB];
@this[IndexB] = Temp;
return @this;
}
/// <summary>
/// Swap item to the left
/// </summary>
/// <typeparam name="T">Collection type</typeparam>
/// <param name="this">Collection</param>
/// <param name="Index">Index</param>
/// <returns>New collection</returns>
public static IList<T> SwapLeft<T>(this IList<T> @this, Int32 Index)
{
return @this.Swap(Index, Index - 1);
}
/// <summary>
/// Swap item to the right
/// </summary>
/// <typeparam name="T">Collection type</typeparam>
/// <param name="this">Collection</param>
/// <param name="Index">Index</param>
/// <returns>New collection</returns>
public static IList<T> SwapRight<T>(this IList<T> @this, Int32 Index)
{
return @this.Swap(Index, Index + 1);
}
#endregion Alter;
#region Action;
/// <summary>
/// Execute action at specified index
/// </summary>
/// <typeparam name="T">Collection type</typeparam>
/// <param name="this">Collection</param>
/// <param name="Index">Index</param>
/// <param name="ActionAt">Action to execute</param>
/// <returns>New collection</returns>
public static IList<T> ActionAt<T>(this IList<T> @this, Int32 Index, Action<T> ActionAt)
{
ActionAt(@this[Index]);
return @this;
}
#endregion Action;
#region Randomize;
/// <summary>
/// Take random items
/// </summary>
/// <typeparam name="T">Collection type</typeparam>
/// <param name="this">Collection</param>
/// <param name="Count">Number of items to take</param>
/// <returns>New collection</returns>
public static IEnumerable<T> TakeRandom<T>(this IEnumerable<T> @this, Int32 Count)
{
return @this.Shuffle().Take(Count);
}
/// <summary>
/// Take random item
/// </summary>
/// <typeparam name="T">Collection type</typeparam>
/// <param name="this">Collection</param>
/// <returns>Item</returns>
public static T TakeRandom<T>(this IEnumerable<T> @this)
{
return @this.TakeRandom(1).Single();
}
/// <summary>
/// Shuffle list
/// </summary>
/// <typeparam name="T">Collection type</typeparam>
/// <param name="this">Collection</param>
/// <returns>New collection</returns>
public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> @this)
{
return @this.OrderBy(Item => Guid.NewGuid());
}
#endregion Randomize;
#region Navigate;
/// <summary>
/// Get next item in collection and give first item, when last item is selected;
/// </summary>
/// <typeparam name="T">Collection type</typeparam>
/// <param name="this">Collection</param>
/// <param name="Index">Index in collection</param>
/// <returns>Next item</returns>
public static T Next<T>(this IList<T> @this, ref Int32 Index)
{
Index = ++Index >= 0 && Index < @this.Count ? Index : 0;
return @this[Index];
}
/// <summary>
/// Get previous item in collection and give last item, when first item is selected;
/// </summary>
/// <typeparam name="T">Collection type</typeparam>
/// <param name="this">Collection</param>
/// <param name="Index">Index in collection</param>
/// <returns>Previous item</returns>
public static T Previous<T>(this IList<T> @this, ref Int32 Index)
{
Index = --Index >= 0 && Index < @this.Count ? Index : @this.Count - 1;
return @this[Index];
}
#endregion Navigate;
#region Clone;
/// <summary>
///
/// </summary>
/// <typeparam name="T">Collection type</typeparam>
/// <param name="this">Collection</param>
/// <returns>Cloned collection</returns>
public static IEnumerable<T> Clone<T>(this IEnumerable<T> @this) where T : ICloneable
{
return @this.Select(Item => (T)Item.Clone());
}
#endregion Clone;
#region String;
/// <summary>
/// Joins multiple string with Separator
/// </summary>
/// <param name="this">Collection</param>
/// <param name="Separator">Separator</param>
/// <returns>Joined string</returns>
public static String Join(this IEnumerable<String> @this, String Separator = "")
{
return String.Join(Separator, @this);
}
#endregion String;
}
How about ...
public static bool IsWinXPOrHigher(this OperatingSystem OS)
{
return (OS.Platform == PlatformID.Win32NT)
&& ((OS.Version.Major > 5) || ((OS.Version.Major == 5) && (OS.Version.Minor >= 1)));
}
public static bool IsWinVistaOrHigher(this OperatingSystem OS)
{
return (OS.Platform == PlatformID.Win32NT)
&& (OS.Version.Major >= 6);
}
public static bool IsWin7OrHigher(this OperatingSystem OS)
{
return (OS.Platform == PlatformID.Win32NT)
&& ((OS.Version.Major > 6) || ((OS.Version.Major == 6) && (OS.Version.Minor >= 1)));
}
public static bool IsWin8OrHigher(this OperatingSystem OS)
{
return (OS.Platform == PlatformID.Win32NT)
&& ((OS.Version.Major > 6) || ((OS.Version.Major == 6) && (OS.Version.Minor >= 2)));
}
Usage:
if (Environment.OSVersion.IsWinXPOrHigher())
{
// do stuff
}
if (Environment.OSVersion.IsWinVistaOrHigher())
{
// do stuff
}
if (Environment.OSVersion.IsWin7OrHigher())
{
// do stuff
}
if (Environment.OSVersion.IsWin8OrHigher())
{
// do stuff
}
Another one, this time to make UriBuilder more friendly when dealing with query params.
/// <summary>
/// Adds the specified query parameter to the URI builder.
/// </summary>
/// <param name="builder">The builder.</param>
/// <param name="parameterName">Name of the parameter.</param>
/// <param name="value">The URI escaped value.</param>
/// <returns>The final full query string.</returns>
public static string AddQueryParam(this UriBuilder builder, string parameterName, string value)
{
if (parameterName == null)
throw new ArgumentNullException("parameterName");
if (parameterName.Length == 0)
throw new ArgumentException("The parameter name is empty.");
if (value == null)
throw new ArgumentNullException("value");
if (value.Length == 0)
throw new ArgumentException("The value is empty.");
if (builder.Query.Length == 0)
{
builder.Query = String.Concat(parameterName, "=", value);
}
else if
(builder.Query.Contains(String.Concat("&", parameterName, "="))
|| builder.Query.Contains(String.Concat("?", parameterName, "=")))
{
throw new InvalidOperationException(String.Format("The parameter {0} already exists.", parameterName));
}
else
{
builder.Query = String.Concat(builder.Query.Substring(1), "&", parameterName, "=", value);
}
return builder.Query;
}
Gets the root domain of a URI.
/// <summary>Gets the root domain of any URI</summary>
/// <param name="uri">URI to get root domain of</param>
/// <returns>Root domain with TLD</returns>
public static string GetRootDomain(this System.Uri uri)
{
if (uri == null)
return null;
string Domain = uri.Host;
while (System.Text.RegularExpressions.Regex.Matches(Domain, @"[\.]").Count > 1)
Domain = Domain.Substring(Domain.IndexOf('.') + 1);
Domain = Domain.Substring(0, Domain.IndexOf('.'));
return Domain;
}
Easily serialize objects into XML:
public static string ToXml<T>(this T obj) where T : class
{
XmlSerializer s = new XmlSerializer(obj.GetType());
using (StringWriter writer = new StringWriter())
{
s.Serialize(writer, obj);
return writer.ToString();
}
}
"<root><child>foo</child</root>".ToXml<MyCustomType>();