share
Stack OverflowWhat are your favorite extension methods for C#? (codeplex.com/extensionoverflow)
[+478] [150] bovium
[2008-11-07 06:47:21]
[ c# .net open-source extension-methods ]
[ http://stackoverflow.com/questions/271398/what-are-your-favorite-extension-methods-for-c-codeplex-com-extensionoverflow ]

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.

Now the first code is committed to the Codeplex site. - bovium
(7) If possible, I'd vote for Google Code instead of Codeplex for the subversion support. - chakrit
(15) You have subversion support on Codeplex. - bovium
(1) I know... but I doubt it'll be as solid as Google's because they allow subversion over svnbridge instead of natively. - chakrit
Btw, perhaps, shouldn't the project have a proper name of its own? Maybe something like ExtensionOverflow? Since SO deserves some mention, else we could just add all this to some existing project like LinqExt instead of starting fresh. - chakrit
(1) @chakrit Point taken. The name of the project is now extension overflow - bovium
lol... I'm checking it out now.. - chakrit
count me in... I am on codeplex as chakrit. same username - chakrit
(3) Meh. I would join if it weren't on codeplex. +1 for google code. - BrightUmbra
Erik unfortunately everything is started now on codeplex. Please join anyway. - bovium
really... Google Code pretty please? - chakrit
(5) The problem with codeplex is the speed - the site is horribly, horribly slow. - BrightUmbra
Extension method madness ... - Pop Catalin
@bovium are you still there? - chakrit
I'm still here yes!!! ;-) Just not as active as I would like to be. Thats the problem with a day job. - bovium
There is also Mono.Rocks which provides many useful extension methods - Pondidum
I'd be happy to join on codeplex! Name over there is RogueCommanderIX. - RCIX
(8) The only reason the language purists aren't turning in their graves is because they're still alive ;) - Luke Puplett
Is this still active? I'd like to join the fun - jdelator
The codeplex page is empty... - KdgDev
(3) Looks pretty good. I do have a comment about naming the static classes. Naming them <type>Extensions isn't very informative. For example StringExtensions holds both formatting and xml stuff. I think it's better to name the class with why you're extending that type. For example UnixDateTimeConversions. You can reasonably guess it holds methods for converting to and from Unix time. Just a thought! - ecoffey
Check this URL for more about C# Extension Methods planetofcoders.com/c-extension-methods - Gaurav Agrawal
[+232] [2009-05-07 08:29:19] Winston Smith
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....
}

(2) I like it! clean... - Steve
Made this too. One of the rare things i miss from Visual Foxpro. :) - Arnis L.
This code doesn't compile. Array's don't have Contains method - Ryu
(2) Well it compiles if you're using System.Linq; - Ryu
(10) Maybe "EqualsAnyOf" would be a better name than "In"? - Tom Bushell
(10) I'm not sure I like it - I like the brevity of In, but maybe IsIn would be better. - Winston Smith
(50) Using the same Contains method: (new[] { 1, 2, 3 }).Contains(a) - Max Toro
It think using Any better of Contains. But it seems harder to achieve... - Fitzchak Yitzchaki
Visual Studio error: Error 2 'System.Array' does not contain a definition for 'Contains' and no extension method 'Contains' accepting a first argument of type 'System.Array' could be found (are you missing a using directive or an assembly reference?) - KdgDev
Problem: this requires than 1 parameter. In which case, best to just use the LINQ contains method, right? - KdgDev
I would probably write two extension methods - IsInOne() and IsInAll() - BuddyJoe
@webDevHobo - System.Linq is the required using statement, also that means you have to have either linqBridge.dll or .net 3.5 or higher. Contains - msdn.microsoft.com/en-us/library/bb339118.aspx LinqBridge - code.google.com/p/linqbridge - Maslow
(4) I thought of In<T>(...) as well and found it to be the most useful extension method outside of the standard library. But I am at odds with the name In. A method name is supposed to be describing what it does, but In doesn't do so. I've called it IsAnyOf<T>(...), but I guess IsIn<T>(...) would be adequate as well. - JBSnorro
(1) The name makes perfect sense, especially if you've used similar functionality in MySQL. dev.mysql.com/doc/refman/5.5/en/… - jeremysawesome
1
[+160] [2008-11-07 07:21:31] Jon Skeet

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/miscutil
[2] http://www.pobox.com/~skeet/csharp/miscutil/usage/genericoperators.html

(1) That's nice! You should put it up on Google Code or CodePlex so I can send you some patches :-) I promise it'll be readable :-P - chakrit
Yes, I'll move it to Google Code some time... and rename it at the same time, probably! (MiscUtil is a terrible name.) - Jon Skeet
Yes please put it some place where we can see the code. - bovium
(3) @bovium: You can already see the code. Follow the link in the first sentence - full source is there. - Jon Skeet
@Jon Skeet. Can I use the code and put it in the Codeplex project? - bovium
(1) @bovium: I'd rather do it myself, putting it on code.google.com and manage the project myself, if you don't mind. Obviously you're within the licence to put it on Codeplex if you keep the appropriate attribution, but I'd rather sort it out myself soon unless you're desperate :) - Jon Skeet
(1) @Jon Skeet. Its put under the MIT license free of use for everybody. Commercially or open source. Why not join forces and make an extension methods library for the public. - bovium
(1) Just because I do lots of other bits and pieces in that library. You're welcome to take a copy of it all for your project, but I'd rather keep one copy in my own project too. - Jon Skeet
(1) x.ThrowIfNull seems wrong to me. Your calling a method on what appears to be an instance member checking if its null. I know this will work since extension methods are just static methods, Its just not intuitive. - JoshBerke
@Josh: It's unintuitive to start with, but once you get used to it (which really doesn't take long) it's concise and very readable. Keep your mind open to new ways of doing things :) - Jon Skeet
this is like CHEATING - Faizan S.
(8) @Shaharyar: I have no idea what you mean. - Jon Skeet
Jon, your site says that this is "licensed under the Apache licence...". Which license is correct: MIT/Apache? Thanks - JP.
19.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
(1) @lasseespeholt: Well, in both cases you'd have to have 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
@Jon Ahh good point ;) of cause it could be static so you could do something like 30 * SI.min but that just make it less clear. - Lasse Espeholt
(7) This is probably a good time to not use var. - Buh Buh
2
[+147] [2008-11-07 07:03:41] chakrit

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/f3e2a94d6

(11) It's certainly short - but will be unreadable to any new members of your team. - Jon Skeet
readability is the only reason that I wouldn't use this, apart from that its a good idea - Nathan W
I would name it FormatWith or something. - mmiika
(4) Just rename it however you like... - chakrit
(3) I think readability matters more in the grander scheme of your code than a few shorthand statements that could be quickly looked up/asked. - chakrit
(6) Personally I'd like a separate Formatter object, which the BCL could parse the pattern of once and reuse. That would increase readability and performance. I've asked the BCL team - we'll see... - Jon Skeet
Wasn't that already done? Since this is just another way to call into the BCL? - chakrit
(1) chakrit: No - because every time you format, the BCL will have to parse the format string. Format strings usually remain constant throughout the course of a program's lifetime - why parse them more than once each? - Jon Skeet
(1) What does this accomplish except for adding one more method call... For me it does not look readable at all. - Vyas Bharghava
@Jon_Skeet I see. That'd add more value to the method as well hehe. - chakrit
I don't understand... If you have used string.format before, then you'd certainly can quickly guess that it's a string.format call. And a quick goto definition would tell you that. If you don't like it, just name it 'Format' or whatever you like. Take a look at the '%' format operator in Python. - chakrit
You should add a few overloads that take a fixed number of parameters. Using params is slow! - Rune Grimstad
@Rune I did, I just provided this as example. I have my own version of util extensions lib too. - chakrit
I would call this Substitute - Rob Prouse
You cannot call it "Format" or else it won't compile. I name it "Inject" when I use similar extension - Damir Zekić
(1) I would add some CultureInfo.CurrentCulture and create another CultureInfo.InvariantCulture version. - hangy
(2) Rename "F" to "FormatWith" and it'll be better. The functionality is good, but the name needs to be fixed. - Timothy Khouri
Console.WriteLine already has an overload which formats. Console.WriteLine("{0} {1}", value1, value2) - Stefan Schultze
@stafan-mg it's for example - chakrit
I like the name "FormatBy"... it is a little shorter than "FormatWith" - Alex Baranosky
(3) It's an extension method, of course it's going to be unreadable to new members of the team. I thought that was the idea with this witty stuff? How else will the new members know how clever we are? - MarkJ
other options: .Fmt, .Display, .Macro (as in macro substition)... - klkitchens
(17) Ok... I just went to put this into action and went with .With -- so you get "This is a {0}".With("test") and it's very readable and makes sense. FYI - klkitchens
(2) I joined a new team about 5 months ago and I see this stupid ".F" method used alot. And of course they refuse to change the name... - kirk.burleson
3
[+89] [2008-11-07 12:11:41] xyz

Are these any use?

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

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

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

this mimicks pythons random.choice(seq) function. nice. - Daren Thomas
+1. These are sensible. - RichardOD
(6) Couple things: I'd recommend that OneOf should accept any IList<T>. Then you could always also have an overload that takes a params arg and just passes that into the IList<T> overload. I gave an answer (way down at the bottom right now) with a NextBool method similar to your CoinToss, but with an overload that takes a probability parameter (what if I want something to happen 75% of the time?). Also, just a nit pick: your example code will throw a NullReferenceException since rand is never initialized. - Dan Tao
(3) +1 I really like this, but I prefer CoinToss to be implemented with rng.NextDouble() < .5 because internally .Next(int) is made with .NextDouble() so you would save a cast, a * and a check. - Lasse Espeholt
4
[+76] [2008-11-07 07:30:19] CMS
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))
{
  // ....
}

This is nice, I remember in my last 1.1 framework writing a series of BetweenInt32, BetweenDateTime, etc. - cfeduke
(19) I love this one but I'm trying to decide if it's right to make the bounds check inclusive on the min value but exclusive on the max value. I wonder if that would be confusing. 5.Between(5,10) is true but 5.Between(1,5) is false. Not even sure that a companion Within method would help. Thougts? - Steve Hiner
(12) Wouldn't the name "IsBetween" make more sense? Also maybe make an IsBetweenInclusive and IsBetweenExclusive. No idea which one to take for default though. - fretje
(2) @Steve: it makes more sense if it were a datetime extension. - Joel Coehoorn
(16) To me between implies: 5.Between(5,10) returns false, and 10.Between(5,10) returns false as well. That just feels natural to me. - Alex Baranosky
(3) It seems to me that multiple people have different ideas as to what is natural. Because of this it probably should be explicitly stated what is being used (ie Inclusive vs Exclusive), as this could be a very easy source of errors. - David Miani
(1) Python and Common Lisp both use inclusive on the low end, and exclusive on the high end, as in the code above. Yes, it seems "unnatural" at first, but in the first 5 minutes it becomes tremendously useful -- I would classify it as a miswart. After all, every single character in the above code (except possibly <) seemed "unnatural" to me, at first, too -- writing public static class ComparableExtensions { before my code doesn't exactly seem intuitive. - Ken
I made a similar method but I also added an overload which takes BetweenType enum to specify how the compare should take place. sometimes you want a true between (exclusive) sometimes inclusive and sometimes to include one or the other bounds. - John
(1) Delphi avoids the confusion of "between" by calling their function "InRange", and returning true at the endpoints. I find this is a more helpful name than the ambiguous "between". - Joe White
(1) I'd probably just add an overload with a third param to make it more readable and provide a companion enum Match.Inclusive, Match.Exclusive. Default the third param to make it inclusive, but the overload allows that to be explicitly specified: 5.Between(1, 5); returns true, but 5.Between(1, 5, Match.Exclusive); returns false. - BenAlabaster
Be careful when using it with float or double. The semantics of those differ between IComparer and the < = > operators for infinities and NaNs. That 0 is signed (there are distinct +0 and -0) might create problems too. - CodesInChaos
Default should be inclusive. If someone says to you "Pick a number between 1 and 9", both 1 and 9 is possible answers in most situations. - Espo
Use an enum (neither, lower, upper, both) as a third parameter to specifiy equality on bounds. default to neither. - zzzzBov
5
[+58] [2008-11-07 09:25:16] stiduck

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);

+1 Simple and good =) - Rulas
(15) Would be better as this IList<T> - Will
(21) Just use collection initializer => var list = new List<int>{5,4,8,4,2}; - Arnis L.
Why not just calling List<T>.AddRange(IEnumerable<T> collection) within your method? - Rauhotz
(8) @Will: Actually, it would be best to accept an ICollection<T>; then it could also be used on, for example, LinkedList<T> and HashSet<T>, not just indexed collections. - Dan Tao
@Arnis L this lets you ADD items to an already existing List<T> and can be called multiple times. - Aran Mulholland
I'd rename this to AppendRange() - it makes the difference between this and a collection initializer more obvious. - Joel Coehoorn
Why are you looping the values when you can call list.AddRange(values);? - Stevo3000
(2) Edited to allow covariance in pre-.net 4.0 - BlueRaja - Danny Pflughoeft
Won't compile, problem with the S and T. - KdgDev
I don't have to add a bunch of hard-coded values to a list nearly as often as I need to append values to an IEnumerable generally. When I need to do something like this, I just say 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
Generalized to ICollection<T> - Greg
6
[+55] [2008-11-07 07:11:59] TWith2Sugars

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.
    }
}

I've found myself writing something very similar. - cfeduke
Um, what's with the crazy Substring action though? If you're trying to get rid of the BOM there are much better ways of doing it (such as specifying that it is omitted from the encoding). - Greg Beech
The crazy sub string action came with the code (^_^) - TWith2Sugars
(8) I'd be tempted to call the first one ToXml() (like ToString()) - Jay Bazuzi
Oooh, you are going to get a nasty memory leak there. Make sure you have a private Dictionary<Type, XmlSerializer> and cache them in there. The reason for this is because every time you create a serializer .Net loads a new assembly into your appdomain. - Jonathan C Dickinson
(1) Apologies to the OP if he intentionally wrote it this way, but the use of MemoryStreams AND XmlReader/XmlWriter was overkill. The StringReader and StringWriter class are perfect for this operation. - Portman
Not a problem!, I'll use this altered version myself, thanks. - TWith2Sugars
Just thinking... would it be worth it if we used the "as" keyword and just returned the result as opposed to casting and and catching an exception? - TWith2Sugars
@Jonathan C Dickinson Thanks for the warning! - TWith2Sugars
(2) Beware, this is not threadsafe. You should definitely synchronize your access to the static serialisers dictionary. - Yann Schwartz
@Yann Schwartz How would I start with that? - TWith2Sugars
(2) @Yann, @T, It's much easier if you just add the "thread static" attribute. Then a new cache will be created per thread. No need for synchronization. - Frank Krueger
(1) @Jonathan C Dickinson: It appears from the MSDN docs here msdn.microsoft.com/en-us/library/… that the constructor that is used (new XmlSerializer(type)) does not have a memory leak problem. So maybe the caching code isn't needed? - slolife
@Jonathan, @Yann, @Frank @slolife, @TWith2Sugars - After reading the MSDN link (msdn.microsoft.com/en-us/library/…) provided by @slolife, I think it is safe to say that we don't have to worry about generating a new assembly on every call (as suggested by @Jonathan). I have removed the superfluous caching and cleaned up the code. - Greg
7
[+46] [2008-11-08 11:49:14] chakrit

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


Can we use the code in the codeplex project? - bovium
This is similar to Ruby .each rightÉ - Armstrongest
@bovium sure... @Atomiton I think.. but I don't know Ruby well enough to be sure. - chakrit
+1. I don't know why .NET BCL doesn't have a .ForEach extension for IEnumerable<T> - Judah Himango
I put this up somewhere else on SO, but someone shot it down. Has something to do with that it terminates the expression (i.e. does not return IEnumerable<T>). - Jonathan C Dickinson
(13) Post on why LINQ's IEnumerable<T> extensions don't include a ForEach: stackoverflow.com/questions/317874/… - Neil Whitaker
(13) I recommend reading this before using method: blogs.msdn.com/ericlippert/archive/2009/05/18/… - jpbochi
The Reactive Extensions includes IEnumerable<T>.Run() with many overloads. Apparently Erik Meijer's group is at odds with Eric Lippert's group. - scobi
(2) @jpbochi: This is just Microsoft demagogy - abatishchev
(1) @abatishchev And your comment is just prejudice against Microsoft. It does not invalidade any word written by Eric. Someone's arguments are not made valid or invalid just because of the company he/she works for. - jpbochi
(1) By the way, let me make one point clear. I didn't say you should not use this ForEach extension method. I just said that you should consider the points that Eric exposed before you decide whether to use it or not. I read it and I decided not to use it. You're free to do whatever you want with your code. - jpbochi
@jpbochi: I respect Eric very much. Nevertheless he reads out official Microsoft team's architecture position which I called demagogy - abatishchev
ReactiveExtensions are made for "Reactive" programming. It, naturally, if you understands "Reactive" programming, requires the "Run()" method. There is nothing at odds between the groups. They are simply offering two different ways to code using two different frameworks. - chakrit
8
[+43] [2008-11-08 08:32:33] TheSoftwareJedi

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.html

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

I have an extension method for logging exceptions:

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

And it is used like this:

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

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


(2) Should read public static void Log(this Exception obj){} maybe? - Chris S
I think this is good for BCL or 3rd party exceptions, but if you roll your own exception types, you can place logging in your base exception class. That way you don't have to remember to call Log(). - Si.
10
[+38] [2008-11-07 07:11:02] mlarsen
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:

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.

[1] http://geekswithblogs.net/sdorman/

This enum-parsing scenario comes up all the time... gotta put this in my lib :-) - chakrit
Wow, I've been writing methods to map strings to enums (just started using .NET). Thanks, this will absolutely help! - Kevin
@bovium you should add sdorman to the project. - chakrit
(4) You might also consider naming this ToEnum<>(), since it comes after the object. - Neil Whitaker
Great idea about ToEnum<>(). It has a much clearer meaning. - mlarsen
Note that Enum.TryParse<T> has been added to Net 4.0 - blogs.msdn.com/bclteam - Dan Diplo
(1) I don't think this method should use Trim. Trimming the input should be the responsibility of the caller. - CodesInChaos
11
[+32] [2009-11-19 21:21:22] Juliet

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.


(6) +1 because no one else seems to get it - P Daddy
(2) Can someone be kind enough to explain it to the less gifted of us? - jpbochi
(5) +1 for correct spelling of 'Brillant' - rmx
hahaha Just read the article (Joel's comment above) - funny true, but having been in pretty much the same boat (on the recieving end, not the Paula end) it's only funny looking back! Once had a contractor brought in to work on a project I was designigner/lead dev on - she was not under my direct control, but was assigned work from my teams work list. Bosses lauded her as being brilliant (even hiring her again later as a Dev Lead!). It never dawned on them that every piece of code she wrote or designed had not made it to production and all had to be completely rewritten from scratch by my team! - Wolf5370
12
[+31] [2008-11-07 07:13:53] CMS

DateTimeExtensions [1]

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/DateTimeExtensions

(5) I'd suggest renaming "SetTime" to "WithTime" as it's not actually setting it in the existing value. Nice otherwise though. - Jon Skeet
(1) Agree, "WithTime" sounds better... - CMS
(28) DateTime.Now.First() - first what? It's only apparent from the sample code. - mackenir
(2) Very nice. But agree that the names could be a lot better. - bovium
DateTime.Now.First will be clear enough in Intellisense if the method is well-documented. - Kyralessa
13
[+29] [2008-11-07 07:07:00] sontek

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

[1] http://www.gitorious.org/cadenza

12 fairly basic extension methods. I'm a bit underwhelmed by mono-rocks. - mackenir
(I'm talking about the released version, not the one you need to use source-control to get) - mackenir
(2) It has been obsoleted by Cadenza. gitorious.org/cadenza - Ranhiru Cooray
(3) Can we have examples? - Casebash
14
[+28] [2008-11-07 12:41:24] Venr

Here is one I use frequently for presentation formatting.

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

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

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

Whoah, Pokemon exception handling is gonna hide issues like ThreadAbortException, etc. Please catch something specific. - JBRWilkinson
15
[+28] [2008-11-14 21:02:46] Jesse C. Slicer

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();
        }
    }

Not used that often, but very cool indeed! - peSHIr
(26) No wonder the empire fell. - Paul Ruane
That reminds me of the Python PEP 313, which was an April Fools joke to include Roman Numeral literals in python: python.org/dev/peps/pep-0313 - torial
16
[+25] [2009-10-09 12:51:49] Paolo Tedesco

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
        };
    }
}

In my opinion this is really poor coding style. Constants should be used instead, not obfuscated logic. - xxbbcc
@xxbbcc: If you don't like it, don't use it. - Paolo Tedesco
17
[+24] [2010-07-12 21:57:19] fre0n

For Winform Controls:

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

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

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

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

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

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

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

IsDesignTime Usage:

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

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

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

SetDropdownWidth Usage:

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

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


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

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/extensionmethod

I like this too, Jon has it in his, and I use something similar from Umbrella, could stand to drop "ArgumentIs" part. - cfeduke
Yeah! this is a kewl extension method too :) - Pure.Krome
(3) If you use the ArgumentNullException-constructor with only 1 string-argument, that argument has to be just the parameter name, and not the error message. So your code should look like this: if (obj == null) throw new ArgumentNullException(parameterName); - Tommy Carlier
I'd use default(T) for this and remove the class requirement. - Joel Coehoorn
(1) @Joel: Non-default values for native types are legitimate arguments more often than null values. Checking against null makes more sense to me than checking against default. Of course, I just generalize the whole idea by saying Require.ThatArgument(input != null) or Require.ThatArgument(personId > 0). It doesn't take that much more code, it's a lot more flexible, and it reads nicely. I have additional overrides that take funcs for when you want to customize the error message or the exception itself. - StriplingWarrior
To include names and nullable value types, I do it like this: public static void ThrowIfNull<T>(this T item, string name) where T : class {if (item == null) throw new ArgumentNullException(name);} public static void ThrowIfNull<T>(this T item) where T : class {if (item == null) throw new ArgumentNullException();} public static void ThrowIfNull<T>(this T? item, string name) where T : struct {if (item == null) throw new ArgumentNullException(name);} public static void ThrowIfNull<T>(this T? item) where T : struct {if (item == null) throw new ArgumentNullException();} - Wolf5370
19
[+22] [2009-01-16 12:00:34] chakrit

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

(4) Just a guess, but think about what happens if your T is a struct. - Rauhotz
Don't know but maybe it should have where T : class in there. - chakrit
You still have to put a variable name in front of every method/property call. Why not just make your original variable name shorter? - Joel Mueller
@Joel Muller it's not always my variable... think Someone.Else.Namespace.With.WeirdClass.Instance - chakrit
(5) I also use the c# 3.0 property initializer syntax wherever possible to achieve the same result. - Steve
@Steve wanna share how? - chakrit
(3) @chakrit, here's an example. It only applies when creating the object Button n = new Button { Name = "Button1", Width = 100, Height = 20, Enabled = true }; - Steve
@Steve I see... : - ) - chakrit
(1) This would be useful for when you have a lot of events to hook up, because C#'s property initializer syntax doesn't support events. - Gabe
(1) this is also userful outside of property initializers, because you can only use them when creating a new object. this extension can work on previously created objects. - boomhauer
So, what's wrong with simply writing { var x = someVeryVeryLonggggVariableName; /* do something with x */ }? - Heinzi
@Heinzi You get a new scope (the With block scope) and the ability to inline complex access to the object. Also, it doesn't interrupts your train of thoughts as much since you don't have to backtrack and put it in a variable. See: msdn.microsoft.com/en-us/library/ms172864(VS.80).aspx ... - chakrit
20
[+18] [2008-11-09 04:43:44] µBio

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


The Aggregate in Capitalize is pretty bad for performance, because it creates many string instances. Why not use word.Substring(1) instead ? - Thomas Levesque
21
[+17] [2009-06-05 20:39:33] Vasu Balakrishnan

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(....)

Yes, if someone forgot "Null Object Pattern" this method is useful to patch it. Collection should never be null. - Pavel Hodek
This scares me slightly - GoatInTheMachine
22
[+16] [2008-11-07 07:09:11] CMS

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

(13) You should use Decimal for currency else you'll get rounding issues - Andrew Bullock
What about use an Enum in the parameter instead of plain string - Rulas
(2) @ Rulas : because there isn't a fixed number of cultures... - Thomas Levesque
23
[+15] [2009-08-09 13:02:34] Chris S

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.aspx
[2] http://www.west-wind.com/WebLog/posts/197245.aspx

Very usefull method, but I don't think it should be and extension method. - Pop Catalin
If you're writing a text editor it probably warrants an extension method, but I agree most of the time it's probably no more than a static private method - Chris S
24
[+15] [2010-10-01 19:48:23] scobi

Here's one I just created today.

// requires .NET 4

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

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

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

It lets you do this:

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

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

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

(1) What if I want thingy.NullOr(t => t.Count), where Count is an int ? You should return default(TReturn) rather than null, that way you won't need the class constraint and it will work for value types too - Thomas Levesque
(2) TIn should be required to be a class, otherwise this entire extension method makes no sense (value types cannot be null). And your example with t.Count does work with the above extension method. Could you take a second look? - scobi
@Scott: this is a useful method to a common problem. However, I believe TReturn elseValue = default(TReturn) is only available to .NET 4.0? I have 3.5 SP1 and I've never seen that construct (neither has my compiler). I just moved this to inside the method. One issue, however, is that boxing a nullable type to object for use with the method yields an unexpected result (0 vs expected null). - Jim Schubert
@Jim: the default(T) keyword has been there since VS2005, but I think default parameters is a new .NET 4 feature. The easy way around it should be to have two variants, one that takes the param and one that does not. I'll update the answer to be CLR 2.0 compatible. Regarding the boxing - that's the point of default. It will be 0-initialized data for a value type, and null for all reference types. A TReturn of a value type should remain unboxed all the way through the function. - scobi
@Scott: My question was about the default parameter, which I've only seen in dynamic languages like Ruby. My point regarding nullable types is that returning x.Value should return null (if, for example, int? was null) or the value if int? has a value. Returning 0 when int? x = null is passed and boxed to object is an odd case. I've seen similar checks for nullable types in libraries such as fluent nhibernate and linfu (I think) for this specific case, allowing you to drop the class constraint as previously suggested. - Jim Schubert
@Jim I believe the default param like that is also possible in C++. I don't know why it would only be common in a dynamic language, because it is a statically typed feature (template params are known at compile time). Regarding 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
Also: there is already Nullable<T>.GetValueOrDefault(). - scobi
@Scott: Thanks for mentioning the default parameters in C++. I have seen them in C++, but that was in school and I had long since forgotten about them. In Ruby, they're called "optional parameters" instead of "default parameters" and I associated them with dynamic languages because they force the type of the parameter. In Ruby's case, the variable's type can't be changed but the variable can be reassigned. I have heard about default parameters in VB.NET under 3.5 and it's enough for me to upgrade to 4.0. You're right, though, about there being little added value for nullables. - Jim Schubert
... I just thought the side effects of boxing a struct were worth mentioning. - Jim Schubert
25
[+14] [2008-11-07 21:10:34] Adam Lassek

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);
}

(2) This should also work as an extension method for IDataReader. - hangy
(2) Actually, make the "this" parameter of type IDataRecord for maximum compatibility. In my version of this, I have an overload that takes an ordinal, which the fieldName version calls. Saves the "GetOrdinal" followed by a lookup by name. - Joel Mueller
There is a proper implementation, that can deal with any value type: rabdullin.com/journal/2008/12/6/… - Rinat Abdullin
Thanks Rinat, I have actually got this down to a single generic method - see stackoverflow.com/questions/303287 - Adam Lassek
All of these methods appear to be un-needed as you can use the as keyword to get a value from a reader allowing for null. If you combine the null coalescing ?? operator with the as operator you can even have a non-null default value for going directly to a value type. See stackoverflow.com/questions/746767/… - Stevo3000
@Stevo No, you can't use as in this way. Did you test this? DBNull values will throw an exception. - Adam Lassek
@Adam Lassek - Actually yes I have tested this and have it running in a production environment. I have no idea where you got the impression that an exception would be thrown if a value is DBNull, it really wont; that is data access 101. - Stevo3000
@Steve, Im thinking this is provider-dependent.. Ive had oracle providers blow up on DBNull balues, but some others didnt. Been too long though, I'm probably wrong ;) - boomhauer
I recommend seeing if can do this for strongly typed datatables? they also dont allow nullable types, and are a huge pain to work with. In fact they are much worse, because if you try to access a field that has a null, the access itself throws an exception.. it doenst even return a dbnull you can inspect. - boomhauer
26
[+14] [2008-11-09 18:51:34] Michael Stum

"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/
[2] http://stackoverflow.com/questions/228038/best-way-to-reverse-a-string-in-c-20

Doesn't String already implement IEnumerable<char>? So you'd just need to do return new String(input.Reverse()); - Iain Galloway
An implementation using StringBuilder should be faster. - CodesInChaos
(1) @CodeInChaos The Benchmarking in stackoverflow.com/questions/228038 measured that StringBuilder is slower. - Michael Stum
You're right. It seems like the thread safety requirements (probably to ensure immutability of the string returned by ToString) slow StringBuilder down a lot. - CodesInChaos
(2) Hope you don't encounter any surrogates or combining characters. - dalle
Or even string newlines of the form "\r\n". Or double newlines of the form "\n\r", for that matter. - aboveyou00
27
[+14] [2009-05-13 15:36:29] Joel Mueller

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.


28
[+13] [2008-11-11 08:22:26] spoon16

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);
    }
}

Check out MvcContrib.FluentHtml - Arnis L.
This probably should be duplicated with Literal instead. - Mark Hurd
29
[+12] [2010-03-31 05:36:00] Max Toro

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/

30
[+11] [2010-09-30 20:52:39] mattmc3

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%28v=VS.100%29.aspx

(1) Very similar in purpose to the method I posted here. Your implementation allows more flexible patterns, but mine is probably faster ;) - Thomas Levesque
31
[+10] [2008-11-07 12:42:59] user35385

Find more examples here: www.extensionmethod.net [1]

[1] http://www.extensionmethod.net/

Oh Dear, extensionmethod.net appears to have been SO'd - seanb
32
[+10] [2010-06-23 03:06:18] johnc

Similar 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.


And what purpose of all these? Why not just write, say, "item as Type" instead of "item.As<Type>()" as you do? - Kamarey
(2) @Kamarey It is a subjective preference, but it reduces confusing parens that can build up when you have multiple casts. item as Type becomes (item as Type) or ((Type)item) if you need to use item as the cast type. Also, the left to right scanning of item.As<Type>(). ... is much more readable over boxing in some confusing cases. I did say it was simple, and I agree it is subjective, but I find it can be quite powerful in code readability. - johnc
(1) @Kamarey some people call this "fluent" programming - always programming left to right, never having to back up to put parens on things. Reaching for the arrow keys slows things down. It also keeps in style well with Enumerable and Observable operators. @johnc I would add a To<T> to the list that does (T)item. - scobi
33
[+9] [2008-11-07 07:20:43] TWith2Sugars

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

Yup, same ToInt64, ToFloat, etc. You can eliminate the if and knock it down to one return if you like. - cfeduke
No example code!!! - bovium
ah ha I used to have a bunch of these as well. But it was kind of too large when you want string.ToInt32 double.ToInt32 float.ToInt32.. blah blah I think I've overused it a bit :-) - chakrit
(4) converting to string to then convert to something else? yuck... - Pablo Marambio
Pablo Marambio - any alterative ways I could perform this? - TWith2Sugars
(6) Convert.ToInt32(object)? - spoon16
(2) If I remeber correctly convert.ToIt32 could throw an exception - TWith2Sugars
I have a similar method called Parse<T> that I use for all sorts of types, not just int32 - John
34
[+9] [2010-01-06 21:15:17] jpbochi

IEnumerable<> Shuffle

I 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_shuffle
[2] http://stackoverflow.com/users/105570/dan

(1) If your intention is for this method to be used within LINQ queries, then you might want to consider implementing a ShuffledEnumerable 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
(1) @Dan: This is a great point. There's an elegant way to use deferred execution without an explicit declared class, though. yield return solves the problem. I'll edit my answer. - jpbochi
(1) Solid. Now it's basically the logical opposite of OrderBy. Nicely done! - Dan Tao
Just found a slightly more flexible version here: stackoverflow.com/a/5807238/123897 - jpbochi
You should remove the foreach loop and replace the body of the if statement with yield return array[k] = array[n]; - aboveyou00
35
[+9] [2010-03-13 18:45:15] Dan Tao

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);
    }
}

36
[+8] [2008-11-09 04:56:32] TraumaPony
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;
    }

}

+1 for use of the little-known .NET 4.0 design-by-contract APIs. - Judah Himango
(3) Isn't it somewhat dangerous to already enumerate "enumerable" by calling "Count" on it in a contract check? Or is this not a runtime check? - flq
It's still dangerous because some enumerables can only be iterated once, but I fixed it so that at least it stops after two iterations rather than determining the entire count. - Joel Coehoorn
37
[+8] [2008-11-11 07:36:56] Jay Bazuzi

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


(1) FileInfo and DirectoryInfo is rather slow compared to their string File and Directory counterpart. You might want to profile those. - chakrit
38
[+8] [2008-11-13 10:29:15] olmo

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 :)


Can we use the code in extensionoverflow on CodePlex? - bovium
39
[+8] [2008-12-06 10:41:00] Rinat Abdullin

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/

40
[+8] [2009-09-22 15:08:31] Konamiman

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;
}

41
[+7] [2008-11-07 09:54:28] Pure.Krome

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(" ", "_");
        }
    }
}

(4) On the IsNullOrEmpty one I'd hate to call it on a million-item enumerator. It would loop through all million items just to tell me it's not empty. Better: return iEnumerable == null || !iEnumerable.Any(); - Joel Mueller
Oh dude - awesomesauce! i never knew that! cheers heaps dude. (my post above, edited.) - Pure.Krome
Glad you like it. One thing - Any() returns a boolean, so <= 0 probably won't compile. If the enumerable is empty, Any() will return false. This font makes it hard to see, but my original example has an exclamation point in front of the call to Any. - Joel Mueller
cheers :) fixed. - Pure.Krome
@Pure.Krome Can I use the code in the codeplex project. And do you not want to become a contributer to that project? - bovium
Yes and sure :) codeplex name is purekrome. cheers! - Pure.Krome
ToPluralString() is just plain simplistic. English is not my native language so it seems silly to me, but it does not even work very well in English in general. ;-) - peSHIr
@peSHIr : care to give an example? basically, for a large number (lets keep this simplistic and say 'the majority') of 'things' that are either 0 or 2+ .. end with an s to define that they are plural (or none for 0). eg. cat/cats. dog/dogs. friend/friends. bug/bugs. Now, this won't work for things like fairy/fairies (and all other words that end in 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
@Pure.Krome: You already give examples yourself. ;-) Some more: index/indices, saldo/saldi and other Latin based ones. If this is just a helper for use in ToReadableTime() - where it would work great, even if that is not globalized in any way, but the function is not used (?) - I would have expected ToPluralString() to be private instead of public. - peSHIr
42
[+7] [2009-07-15 08:36:59] Kenny Eliasson

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.


What if the list is empty in the first code ? - Alex LE
(1) I called my version of this ToDelimitedString to avoid confusion with the built-in LINQ Join method. - Joel Mueller
43
[+7] [2009-11-19 21:47:02] Thomas Levesque

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.


44
[+7] [2010-04-22 01:56:27] Mark Rushakoff

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));

45
[+7] [2010-09-21 03:47:04] benPearce

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);
}

(1) We have some similar ones in our codebase: IsBefore(), IsOnOrBefore(), IsOnOrAfter(), IsAfter(), IsBeforeToday(), IsAfterToday(). They wrap rather trivial code, but they improve readability significantly. - KeithS
46
[+6] [2008-11-08 11:53:04] bruno conde

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));
    }
}

(2) This is not using Extension Methods. Its just a static class. - bovium
(1) To make that an extension method change: static public bool CompareFiles(string path1, string path2) to static public bool IsSameFileAs(this string path1, string path2); then use like: if (file1.IsSameFileAs(file2) - Armstrongest
(1) Two different files on different drives might coincidentally have the same FileIndex. You need to compare VolumeSerialNumber also - but then your example will fail, since VolumeSerialNumbers are different. - Rasmus Faber
See also stackoverflow.com/questions/410705/… - Rasmus Faber
(4) Shouldn't you be closing those file handles? - marijne
47
[+6] [2008-11-09 05:17:59] Zack Elan

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', '_');
}

(1) Use 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
(4) Better use TryGetValue, you're doing two lookups instead of just one. - Anton Tykhyy
48
[+6] [2009-01-05 21:15:47] cseg

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'


You could also do: Console.Write(dummy.ToDictionary().Select(p => string.Format(p.Key + "='" + p.Value + "'"))); so no need for the ForEach extension - chakrit
49
[+6] [2010-03-30 22:22:40] John Leidegren

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.


50
[+6] [2010-06-03 14:28:39] Si.

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;
}

(2) There's a separate keys collection property in the dictionary that might be able to do this faster - Joel Coehoorn
(1) Good thinking Joel, updated answer (and my own code:) - Si.
(2) If you need case insensitive keys, you can pass StringComparer.InvariantIgnoreCase to the dictionary constructor - Thomas Levesque
@Thomas - Even better! Assumes you have access to the ctor, but definitely the best approach. - Si.
51
[+5] [2008-12-11 02:07:57] Mark Cidade
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".


(2) Performance is horrible with Compile(). - Rinat Abdullin
For what I use it for (Web UIs) it's acceptable. - Mark Cidade
For string formatting performance and madness you may want to check out Phil Haack's blog about different ways of doing it ... haacked.com/archive/2009/01/14/named-formats-redux.aspx - WestDiscGolf
52
[+5] [2008-12-29 18:43:37] Mark Maxham

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;
}

53
[+5] [2010-02-06 04:36:31] Jordão

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.html
[2] http://codecrafter.blogspot.com/2008/07/c-extension-methods-and-null-references.html

54
[+5] [2010-10-14 16:52:10] scobi

Here'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!


Not sure what I think of using @this as the parameter name. On the one hand since it's an extension method you can think of it as a regular class method. On the otherhand, using a (common) keyword as a parameter name rubs me the wrong way. Sounds interesting though. - Davy8
I originally picked up @this somewhere on a blog or maybe here on SO. Initially I had the same misgivings, but I've been using it for all my extension methods for the past few weeks and have grown to really like it. I think the "can think of it as a regular class method" outweighs pretty strongly the concern about reusing a keyword. I did think about using "th" or "self" for names, but I especially like how the @ really jumps out. It constantly reminds me what kind of method I'm in. - scobi
Hey Scott, I don't really have much experience with Tasks or Rx and I'm having a hard time following the implementation of this method. Is this useful for when evaluating individual items in a sequence is expensive (thus warranting async eval)? Does it create a new thread for each item or does it reuse the same job thread as more items are pushed? - Sam Pearson
This is useful for when the sequence is expensive. A single thread is pulled from the pool to walk the enumerable asynchronously. It does not return until the enumerable is completed or an exception is thrown. Technically, none of the dispatcher stuff is necessary for this example.. I included it because I write a lot of WPF code and this is a frequent pattern of mine: send a task go do something, publish it as an observable, dispatching the results through the UI thread's message queue. - scobi
(3) Any reason why enumerable.ToObservable(Scheduler.TaskPool) doesn't solve the same problem? - Richard Szalay
@Richard - nope! Didn't know about that function. :) - scobi
55
[+5] [2010-10-22 22:11:21] KeithS

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)

56
[+5] [2011-01-14 08:20:29] HuseyinUslu

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()

Nice one! Would you know how to do the same with WPF (not using GDI)? - Thomas Levesque
Never tried with WPF yet. - HuseyinUslu
57
[+4] [2008-11-08 22:23:49] Timothy Khouri

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...
    }
}

58
[+4] [2010-02-16 23:09:22] HackedByChinese

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

59
[+4] [2010-05-14 08:09:12] ytoledano

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));
}

Surely if it is null, the call will fail (I once tried to implement an IsNullOrEmpty method on a string and felt foolish when I realised), but it would work well for value types - johnc
Nullable tpyes have a HasValue property built into them. - Daniel
@johnc, no the call will not fail if o is null. Extension methods are actually static methods, not instance methods. And the IsNullOrEmpty extension method works fine for me... - Thomas Levesque
60
[+4] [2010-05-16 16:41:23] Thomas Levesque

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>();

61
[+4] [2010-07-19 16:10:39] Tadas

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;

How about using IEnumerable instead of ICollection and Any() instead of Count? - brickner
@brickner IEnumerable<T>.Any() - only generic IEnumerable<T> has Any(). - Tadas
62
[+4] [2010-07-23 11:05:38] Dusty Roberts

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();

(1) And the reverse is already included with .NET as a built-in extension method (yeah, that sounds weird, built-in extension method): stackoverflow.com/questions/208532/… - NickAldwin
63
[+4] [2010-08-26 15:25:13] fre0n

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:

Handled 1
Handled 2
Handled 3
Start executing important stuff
Finished executing important stuff

[1] http://stackoverflow.com/questions/1916095/how-do-i-make-an-eventhandler-run-asynchronously/1916241#1916241

64
[+4] [2010-10-14 18:42:46] Richard Szalay

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/

65
[+4] [2011-01-29 18:58:36] Steve Potter

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;
}

How is it different from TakeWhile? (except for the overloads with Action) - Thomas Levesque
66
[+3] [2008-11-07 10:07:39] Omer van Kloeten
67
[+3] [2008-11-07 21:18:21] Hugoware

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 --%>

<% } %>

Can we use the code on the codeplex project? - bovium
Anyone can use it - Help yourself - Hugoware
Very nice, could be expanded to first check Query string, then check ViewData, then check SessionState, finally return default value. - John
68
[+3] [2008-11-13 05:30:04] BFree

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 "


69
[+3] [2010-01-28 08:49:04] Gidon

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.


70
[+3] [2010-07-23 18:50:56] Kenneth J

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();

71
[+3] [2010-08-20 00:42:15] Thomas Levesque

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.aspx

nice. Just what I'm looking for :-) - Stimul8d
Why not just use Regex? - aboveyou00
@aboveyou00, for performance mostly. Also, there's no obvious equivalence between a regex and a wildcard pattern, and a wildcard is easier to use if you don't need the full power of a regex. - Thomas Levesque
72
[+3] [2010-09-11 06:40:50] prabir

Would 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.


I've written basically identical code myself on more than one occasion. - Greg D
Interesting. But not exactly extension methods. - fre0n
73
[+3] [2010-10-19 23:18:38] KeithS

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.


(2) How is this an advantage over the default OrderBy and OrderByDescending? - Agent_9191
OrderBy() cannot be chained; each call to OrderBy() sorts by a single projection of the collected type. You could still make it work if the sorting algorithm used were stable like MergeSort, but the built-in sorting helper is an unstable QuickSort, so there's no guarantee of maintaining relative order when sorting by equal terms. Chaining OrderBy() would also run an O(nlogn) function once for each OrderBy(); this set of methods sorts once no matter how many terms you compare. - KeithS
This could be improved by avoiding the ToArray(). While OrderBy cannot be chained, you should be able to chain all of the Comparers into an IComparer<T> that you pass to a single OrderBy, right? - scobi
Well, sorting (ANY algorithm) requires knowledge of the entire Enumerable, because the very last element could be the one that comes first in the ordered collection. OrderBy(), behind the scenes, basically does what I'm doing here; slurp the source Enumerable into a finite collection, sort it, then yield through it. - KeithS
(1) Point taken. :) Also: how does this set of classes differ from the Enumerable.ThenBy() and IOrderedEnumerable types in the .NET Framework? - scobi
Actually, it doesn't as written. I didn't know about the existence of ThenBy() when I first wrote this. However, there are some advantages. Because it's a roll-your-own, it's more extensible; for instance, you could add OrderUsing() and ThenUsing() methods that allow passing a Comparison instead of just a projection (allowing sorting based on members that aren't IComparable). You can also performance-tune the sorting by replacing Array.Sort with, for example, a parallel MergeSort. - KeithS
74
[+3] [2011-05-17 13:44:22] takrl

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();

75
[+2] [2008-11-07 07:33:37] Alan

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" } });

Hm, what exactly was wrong with this one? I don't mind the downvote, but I'd honestly like to know if it's not supposed to work or something. - Alan
76
[+2] [2008-11-07 07:55:46] cfeduke

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);
    }
}

You could do that in 2 linq select-where statements. Does that count as BCL? - chakrit
Yes. (Obligatory comment character limit here.) - cfeduke
77
[+2] [2008-11-11 07:22:07] lubos hasko

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());
}

(1) I think it is confusing... - Victor Rodrigues
Maybe something like... guid.NewGuidIfEmpty(); return guid; ...could be better, semantically speaking. - Victor Rodrigues
78
[+2] [2008-11-30 23:02:41] terjetyl

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;
}

79
[+2] [2008-12-01 04:24:27] cbp

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;
}

(1) Problems with these extensions: * All objects are extended (signature pollution) * boxing/unboxing overhead * not all enums derive from int, there could be byte and long as well - Rinat Abdullin
Good points, Rinat. I wish there was a way to write these extension methods. - cbp
(1) If you wanna do that with enumerations change the type object to just Enum. - John Leidegren
80
[+2] [2009-05-07 07:49:28] Stefan Steinegger

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.


81
[+2] [2009-09-16 16:56:26] John Kraft

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.


(1) Would this be better? public static bool IsNull<T>(this T obj) where T : class { return (obj == null); } - Dan Diplo
@Dan Diplo I don't think your change would make any difference at all. It make no difference to use generics to compare an object to null. - jpbochi
(2) The advantage of using generics is this: If you try to call Dan Diplo's generic version of IsNull() on a struct you get a compile-time error. If you call John Kraft's original version it doesn't warn you (and also adds boxing code). - Ray Burns
@Ray Burns You are absolutely correct, however, I consider that to be a plus on mine; it won't throw an exception, and the boxing is the preferred behavior in the code that I am writing. Besides, in the current environment I work in (CRUD line-of-business apps), we never have a need for structs; so it doesn't matter. - John Kraft
For what it's worth, F# has extension properties... - Joel Mueller
It's not a plus because it will always return false on structs. That means that if someone uses it on a struct it is most likely something they did by mistake but they get no error or warning. Considering Dan's method looks identical when you call it (ie, there is no downside to using it) then there isn't any way you could consider your version a plus. - MikeKulls
(1) I'm confused at the concern over structs. A struct, by definition, can never be null. Therefor, the fact that it returns false on a struct is correct behavior. - John Kraft
+1, I use these all the time. I was just about to post an answer with exactly the same code until I found your answer already exists :D - demoncodemonkey
82
[+2] [2009-10-03 00:54:28] Omar

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;
}

(2) Adding " ..." would return ShortenToLength + 4 chars, ie a string longer than what the documentation says. - Simon Svensson
That method needs some TDD unit tests for short inputs. ;-) - peSHIr
@Simon - Fixed the documentation. @peSHIr - I edited it, could you elaborate please. - Omar
83
[+2] [2009-11-02 18:20:57] Greg

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


I would rather use as T instead of casting - jpbochi
84
[+2] [2009-11-20 02:00:15] Thomas Levesque

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);
}

Beware that argument validation should not reside in the same method as the 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
85
[+2] [2009-11-26 17:24:25] tsilb

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;
}

86
[+2] [2009-12-28 13:01:47] Kaveh Shahbazian

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

+1 I particularly liked the Pipe method. I had to download your source to find out that it was like a Where on a single value, though. Could someone edit the answer to make this point clearer? - jpbochi
'Pipe' is different than 'Where'. 'Where' is a 'map' (in mathematical sense and in functional languages) which takes a set (collection & in .NET case an IEnumerable<T>) & a function (which in .NET land is a delegate and can be represented by a lambda expression like x => x > 2; the only restriction on provided predicate is that it must return a Boolean. 'Pipe' operator is a common tool in functional languages. It's main usage is for chaining computations (function calls). It gets a value & a function (like x => f(x)); then it applies the function to the value & returns the result. - Kaveh Shahbazian
(3) I'm afraid some of these I don't like. 500.Sleep() for example... Just a little too cryptic for my liking. I don't see what's wrong with plain Thread.Sleep() - Ian
87
[+2] [2010-06-02 15:18:27] Chao

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;
            }
        }
    }

This is a good one. - JoshJordan
88
[+2] [2010-07-23 18:19:06] Krisc

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).


89
[+2] [2010-08-06 10:57:52] Virtlink

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.


Wow, 8 parameters (not counting the this parameter) ! IMHO, any method with more than 4 parameters needs refactoring... - Thomas Levesque
90
[+2] [2010-10-14 10:46:41] RameshVel

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");

Could be extende to be more generic, too 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/… - SchlaWiener
((src == null || src.Count == 0) ? true : false) == (src == null || src.Count == 0) - Simen Echholt
(7) Why not an IsNullOrEmpty<T>() that accepts an IEnumerable<T>? - jpbochi
(5) By the way, you lost my vote up by appending that ? true : false. - jpbochi
(1) This should be split into two separate answers. The first one is ok (should be IEnumerable<T> instead of List<T>). The second is dubious. I agree with @SchlaWiener, make it generic. I'd also lose the catch. If an exception is thrown, let the caller decide how to handle it. - Greg
(1) The IsNullOrEmpty method is a good idea, I use it all the time (but with IEnumerable<T>, not List<T>)... but I'm pretty sure it has already been posted. Regarding the second method, I see no reason to restrict it to FileInfo. Also, passing a string with the property name is a bad idea: you can do the same with a delegate, and you avoid the overhead of reflection - Thomas Levesque
91
[+2] [2010-10-15 08:36:13] Will Vousden

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] http://stackoverflow.com/questions/2123608/is-this-a-valid-pattern-for-raising-events-in-c

There is an issue with this solution: you can only use it if the event is declared in the current class, not if it's declared in a base class... - Thomas Levesque
@Thomas: Isn't the same is true for raising events manually? The solution is to use the protected virtual void OnBar(Eventargs e) pattern outlined here: msdn.microsoft.com/en-us/library/hy3sefw3%28VS.80%29.aspx. - Will Vousden
Yes, but what I mean is that your solution doesn't work in the general case - Thomas Levesque
(1) @Thomas: Of course, but it isn't intended to :) - Will Vousden
Actually, this is thread-safe in older versions too. I've written identical methods myself. - SLaks
+1 - I generally hate extension methods for Null objects; however, this is a really nice usage! - csharptest.net
92
[+2] [2010-10-15 17:13:07] dejanb

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("&nbsp;", "").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!");

93
[+2] [2010-11-11 09:07:12] Will Vousden

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.aspx

94
[+2] [2011-01-17 15:11:00] Shaul

I 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);
}

(2) All 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
(1) @Jeroen Agreed, although I'd call it GetValueOrDefault to be more in line with other similar methods like FirstOrDefault - Davy8
(1) OK, point taken, I've renamed the method as @Davy8 suggested. - Shaul
@Davy8: excellent suggestion; @Shaul: thanks for fixing it (+1). - Jeroen Wiert Pluimers
95
[+2] [2011-01-18 12:14:53] HuseyinUslu

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();

96
[+2] [2011-04-22 00:10:10] Chuck Savage

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:

  1. You have to include the Microsoft.VisualBasic reference
  2. use the using 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);

I don't know about calling it Open, but these are still good extensions and I'm surprised that nobody has posted them before. - aboveyou00
97
[+2] [2011-10-28 08:40:11] Otiel

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.aspx
[2] http://msdn.microsoft.com/en-us/library/1wdsy8fy.aspx

98
[+2] [2011-12-12 09:24:01] Otiel

Used 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";
}

99
[+1] [2008-11-07 09:15:04] mmiika
(1) It pops up with a password thing. Just press cancel. - bovium
100
[+1] [2008-11-11 01:45:38] community_owned

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 &lt; 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


The code is not complete. - bovium
actually it was complete, but the less than in the for loop was interpreted as a tag... just changed it to < - community_owned
101
[+1] [2008-11-28 21:15:09] Anthony

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.


(1) Why not return the values using yield return and return "actual lazy" enumerators? Would to certain extent take care of your high-performance code comment. - peSHIr
I'd rename these to Append() (and use iterator blocks as suggested by peSHlr) - Joel Coehoorn
Joel, peSHIr: good suggestions, I have updated the answer to do this. - Anthony
102
[+1] [2008-12-10 19:46:28] Robert Dean

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.aspx

103
[+1] [2008-12-29 19:30:19] Mark Maxham

Equivalent 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();
}

(7) You can substitute all the code in this function for one line: return string.Join(separator, list.ToArray()); - jpbochi
104
[+1] [2009-01-08 06:35:26] Th3Fix3r

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();


105
[+1] [2009-01-08 07:57:16] Jonathan C Dickinson

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.


106
[+1] [2009-02-21 13:07:23] andleer

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.


I don't really like this one. The where is already performing the if, that's the whole point of the predicate. - Greg D
Part of the idea here is that some conditionals won't execute on SQL with an IQueryable so you have to separate them. - andleer
107
[+1] [2009-02-21 13:22:05] andleer

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);
{

I like, except I wouldn't say Is or As because doing so implies type comparison/conversion. This is really a parsing method. - Greg
You could go with ParseIsInt32(), ParseToInt32 and ParseAsInt32() - andleer
108
[+1] [2009-07-10 15:59:40] Fredy Treboux

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:

  • What would you think it should happen for value types?, return default? throw?, disable it by generic constraint?.
  • Swallowing NullReferenceException to implement it would be too risky?, What do you propose?, Walking the expression tree executing every call or member access seems difficult and kind of overkill (if at all possible) doesn't it?.

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.


requires .NET 3.5, uses delegates to evaluate object graph in try catch stackoverflow.com/questions/298009/… - usman shaheen
I think it could be a good idea, but it's hard to implement... You can easily check whether x is null, but if you want to perform the check for every level of the "path" (SomeProperty, MaybeAMethod), it gets really hard. I tried to do it by rewriting the expression tree, but I eventually gave up... - Thomas Levesque
(1) This should be a separate question - Casebash
I eventually managed to make it work: tomlev2.wordpress.com/2010/02/21/… - Thomas Levesque
Hey, that's great!. I actually gave it a try a couple of days ago and came up with this: bit.ly/9777Y0 but your approach seems much cleaner. I agree with your conclusions though. - Fredy Treboux
I've got a working project on codeplex... maybe.codeplex.com - Maslow
109
[+1] [2009-09-08 15:10:25] Chris S

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.


Why did they not include that one in the BCL... - John Leidegren
(1) wouldn't ´builder.AppendFormat(format, args); builder.AppendLine();´ be more in the spirit of the stringbuilder (i.e. no temporary string) - adrianm
@adrianm isn't that 1 extra string though (albeit just a \n)? - Chris S
AppendLine uses a static "\r\n" string. string.Format creates a new string every time which need to be GC:d. - adrianm
110
[+1] [2009-11-02 18:36:56] Greg

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


111
[+1] [2009-11-16 15:37:57] Dan Diplo

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.aspx

112
[+1] [2009-11-28 08:42:36] cottsak

Some 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] http://stackoverflow.com/questions/1721327/validate-object-based-on-external-factors-ie-data-store-uniqueness/1741831#1741831

Your IsNullOrTrimEmpty helper is in .NET 4.0 in the form of string.IsEmptyOrWhiteSpace - ICR
@ICR: Hi 5 CLR guys! - cottsak
(1) The BCL guys, but yes, hi 5 indeed. - ICR
113
[+1] [2009-12-28 14:17:49] moomi

For 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];
    }
}


Use as you will for CodePlex or lining your bird cage. - moomi
114
[+1] [2010-03-13 06:26:11] ZaijiaN

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!


115
[+1] [2010-06-23 02:55:22] cbp

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, ", ");

(9) A much faster way to get a delimited string is string.Join(",", strings); where strings is an array. This generates roughly 1/3 the IL as the StringBuilder method. - Jim Schubert
Ah wow, well there you go - cbp
@Jim Schubert: Can you back that up with some benchmarks? The size of the IL isn't a good measurement of speed. Fewer instructions doesn't automatically imply faster running times. - John Leidegren
Just point out that this is still a useful method to have for StringBuilder. If you wanted to seperate the calls to the joining method with other code, then you would have multiple calls to string.Join anyway which would negate any performance benefit over using a StringBuilder. - cbp
@John: Benchmarks have been done on these thousands of times, and they rarely, if ever, show any perceptible performance difference. I'd like to do benchmarks on this to see the difference, and compare string.Join/Format/Concat, StringBuilder.Append/AppendFormat, and + operator concatenation. A 300ms difference in building a string can easily be offset by network and database performance, though. - Jim Schubert
116
[+1] [2010-06-28 13:13:34] John

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);
}

117
[+1] [2010-08-19 16:52:28] Luke Puplett

ASP.NET HTML Encode - short and sweet:

public static string ToHtmlEncodedString(this string s)
{
    if (String.IsNullOrEmpty(s))
        return s;
    return HttpUtility.HtmlEncode(s);
}

118
[+1] [2010-09-21 03:45:01] benPearce

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");

This is a good extension method considering String.Replace does not modify the source string. - Alex Essilfie
119
[+1] [2010-10-22 22:59:58] KeithS

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 

120
[+1] [2010-12-02 20:43:40] Nicholas Carey

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+" ) ;
    }
}

121
[+1] [2011-01-14 12:21:29] Wagner Andrade

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());
}

You could replace everything in your Join<T> method with this: return string.Join(seperator, self.ToArray()). - Pondidum
Oh really, I forgot this method. Thanks, Pondidum! Edited. - Wagner Andrade
122
[+1] [2011-05-17 23:13:53] Gleno

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>();

Even if you cache the MethodInfo in a dictionary, calling MethodInfo.Invoke is still very slow... you should create and cache dynamically created delegates instead - Thomas Levesque
123
[+1] [2011-08-26 08:04:55] sasjaq

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.


124
[+1] [2011-11-09 16:36:35] csharpdev

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(",");

125
[0] [2008-12-17 16:10:04] Mark Cidade
  • 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);
     }
    

126
[0] [2009-01-08 07:54:50] Chris
// 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());
    }

(2) You forgot TrueFalseFileNotFound :P - Thomas Levesque
127
[0] [2009-01-28 08:28:03] Tony Tanzillo

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


128
[0] [2009-06-04 23:53:56] Manish Basantani
// 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.


129
[0] [2009-11-20 02:18:53] RCIX

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

No example ? It's pretty straightforward, but maybe not for everyone - Thomas Levesque
There, how's that? - RCIX
It would be more .NETy if you used IComparer<T> or Comparison<T> (or an overload for each), instead of a "less" function, which smacks of STL. - P Daddy
As i understand it a Comparison<T> is basically a Func<T,T,int> in disguise, where i need a bool to work with the insertion sort. - RCIX
Yes, 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
Accepting 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
Ah, i get it now. I'll change that, thanks! - RCIX
130
[0] [2009-11-26 17:22:18] tsilb

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;
}

131
[0] [2009-11-26 17:44:27] CaffGeek

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);
    }
}

(3) Looks a lot like System.Data.DataSetExtensions.dll that comes with .NET 3.5, except not as efficient. - Joel Mueller
132
[0] [2010-02-16 23:03:26] Alexander Smirnov
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");

(4) This answer was already provided, way up top :( - Dan Tao
133
[0] [2010-03-13 20:55:03] Janko R
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.


134
[0] [2010-07-13 14:08:49] Soonts
// 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 ];
    }
}

135
[0] [2010-10-22 14:23:55] John

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();

(1) There are way too many things wrong with this code. - Jim Schubert
Thanks Jim. Keep up the constructive comments, very useful. - John
@John: no problem. Here's a few issues: You're generating a private class with public accessors. StringBuilder has an 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
(1) Also, I apologize for the laconic answer-- I was at work. Here is an excellent chapter from O'Reilly on reflection which I think will help you to better examine the types you're trying to mimic the code for: oreilly.com/catalog/progcsharp/chapter/ch18.html - Jim Schubert
Should a private class not have any accessors with more visibility than private? I would rather force the programmer to change the visibility than than to assume public or anything else. I realize there is the appendformat and I use it quite often but I also need the new line and unfortunately we don't have and AppendFormatLine. - John
(1) Generally I think you are missing the point entirely. This is not intended to be used as is. More likely it is to be used on a more customized basis. For example, you have a large object you want to represent, either from a DB or a class you don't have access to the source. You run through linqpad to generate the class, make few mods and off you go. - John
BTW: It is my opinion that if you don't have enough time to extrapolate on your negative opinion you should keep it to yourself until such time that you do. Thanks again - John - John
(1) 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
"No. Unless this class is a nested class, which your code doesn't suggest". My code doesn't suggest a thing. It simply generates a class and forces the programmer to decide what the accessibility of the generated class should be. "StringBuilder has AppendFormat() and AppendLine(); Just call them both or write an extension method" That is one way to solve it. I could also use string.Format inside the AppendLine. - John
"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". Please explain this further. Are you saying I should leave it as "String", as it comes through, instead of "string"? "And, IntPtr is platform-specfic so this code only works on 64-bit". All well and good but the code will work in 32 bit. I'm not using IntPtr anywhere. I'm simply representing it as a long if it comes through. As is the case in the example I provided. - John
(1) Implicity-typing string using the 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
(1) In regards to your comment about class-level accessibility defaulting to private: the default access for a class if you leave off the access modifier is 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
Also, if you find yourself using this code pretty frequently, it may be worth it to dish out $125 and by .NET Reflector Pro: red-gate.com/products/reflector Then, you will be able to analyze the exact internals of most .NET libraries. I'm sure you've already heard of it, but others reading this thread may not have. - Jim Schubert
My job is not to make the job of the compiler easier. The job of the compiler is to make my life easier. I take advantage of it whenever possible if it makes sense (We use var quite often at work and it has paid off many times). Using var for strings is perfectly fine in my opinion. I could easily leave the types as what they come through but since this is intended to generate a class that the user will then incorporate into their code then it should be written as they would. Do you use "Int32 x = 5" in your code? The IntPtr is not a bug, as I said before, it will work on 32 bit. - John
I'm well aware of the benefits of reflector. We use the free version all the time. The pro version doesn't have anything additional that I would find useful. As for the private part, again you are missing the point of the code. I'll just leave it at that since this is going nowhere. - John
Final Score: Jim 1 - John 0 - Anonymous Type
136
[0] [2010-11-14 15:22:37] Roman A. Taycher

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.cs

(3) Why do you use method.DynamicInvoke()? A direct call like this: method() is much faster. stackoverflow.com/questions/932699/… - Greg
The stuff I saw showing how to call a lambda used .DynamicInvoke(), I wasn't sure there was a better way. - Roman A. Taycher
(1) Was calling DynamicInvoke() the only thing I did wrong or something else too? If it was something else I'm curious what else caused the downvotes. I appreciate the invoke explanation and would be glad to hear anything else I got wrong. - Roman A. Taycher
(1) I'm not sure why this got a couple downvotes, I don't see anything wrong with the code itself. Maybe the downvoters thought that the methods weren't very C#-ish. You explain that you are borrowing from Smalltalk's style, so I don't see what's wrong with that. - Greg
I don't expect to use the ifTrue/ifFalse on actual code, it was just fun to implement. - Roman A. Taycher
137
[0] [2010-12-24 10:55:54] Chris Job

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.


138
[0] [2011-01-14 08:24:56] HuseyinUslu

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.


I'm pretty sure this one has already been posted before... - Thomas Levesque
It may be, i've not checked all the answers. - HuseyinUslu
139
[0] [2011-04-06 16:04:11] fre0n

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:

  1. Use the static 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).
  2. If thisObject is null, return false. No further comparisons can be made if it is null.
  3. If 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.
  4. If 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.
  5. If both objects are IEnumerable, return whether contain the same items, in the same order, using IsEqualTo to compare the items.
  6. If the objects have different types, return false. Since we know now that thisObject does not have an Equals method, there isn't any way to realistically evaluate two object of different types to be true.
  7. If the objects are a value type (primitive or struct) or a string, return false. We have already failed the Equals(object) test - enough said.
  8. For each property of 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();
        }
    }
}

140
[0] [2011-04-18 21:15:15] David B

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
        );
}

141
[0] [2011-05-06 15:54:04] John

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;
}

142
[0] [2011-08-17 08:01:18] NeverFade

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;
        }

It doesn't have to be specific to persian, you can make it work for any culture (example here). Also, you should use a StringBuilder instead of string concatenation for better performance - Thomas Levesque
143
[0] [2011-08-17 08:04:24] NeverFade

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;
        }

(2) This is a little excessive having something so specific available to every string object in your app. Especially when you can just use myString.Any(c => c != '0') - MikeKulls
tanx for your comment - NeverFade
@MikeKulls, actually it should be myString.All(c => c == '0') if you want to keep the same meaning... - Thomas Levesque
144
[0] [2011-08-26 08:15:16] sasjaq

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);
    }

145
[0] [2012-03-06 23:24:54] jerone

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;

}

146
[0] [2012-03-23 13:11:04] takrl

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
}

147
[0] [2012-04-06 10:22:13] Luke Puplett

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;
    }

148
[-3] [2009-11-26 17:25:29] tsilb

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;
}

(5) This seems a a little flawed in assuming FQDN structure - try these test cases. www.msn.co.uk vs. www.msn.com vs. msn.co.uk co definitely isn't the root domain for msn.co.uk. - stephbu
149
[-13] [2008-11-07 07:17:47] sontek

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>();

(2) The usage is wrong. - bovium
also a duplicate of stackoverflow.com/questions/271398/… - spoon16
Not associated with strings. - abhishek
150