What are your favorite lesser-known .NET Base Class Library classes and methods?

+30  A: 

I didn't know about System.Net.WebClient until it was posted in an answer to a question of mine.

WebClient client = new WebClient ();
client.DownloadFile("", "target.html");
client.UploadFile("", "hello.txt");
John Sheehan
And we don't know about it either, since your answer doesn't say a single word about it.
the linked question says enough
John Sheehan
WebClient is unhandy because it doesn't deal well with mime-types and in particular content-encoding. Better use HttpWebRequest; that at least lets you get at those crucial parts of the response when needed (with webclient, you're stuck)
Eamon Nerbonne
@Eamon, you can easily inherit from WebClient and customize the request before is is sent, so you can add features such as cookies, MIME types, encoding etc. if you want to
Thomas Levesque
+21  A: 


Also StringReader and StringWriter.

Oops forgot about: Debugger.Break

Conditional breakpoints inside large loops. Debugger.Break is great!
VS supports conditional breakpoints when debugging. Just right click on the red point you get when placing a breakpoint and select "Condition"
Sergej Andrejev
+5  A: 


Kent Boogaart
+7  A: 

System.Text.UTF8Encoding for converting streams.

Jason Z
+5  A: 

BaseValidator Makes writing Custom validated controls much easier.

+15  A: 


"The MailDefinition class can be used by controls to create a MailMessage object from a text file or a string that contains the body of the e-mail message. Use the MailDefinition class to simplify creating predefined e-mail messages to be sent by a control."

John Sheehan
+19  A: 

For some reason many people don't kow about System.Text.StringBuilder. I couldn't live without it!

Mitchel Sellers
+78  A: 

This saves a lot of typing on strings:



string.IsNullOrWhiteSpace()  // .NET 4 only

Also a hidden gem using events; when declaring an event, a nice way to make sure you never need to check if it's null, is by initializing it to an empty anonymous delegate at declaration time:

public event EventHandler MyASimpleEvent = delegate {};
Nice technique! Don't know why I never thought of this myself... +1!
this may cause a problem with asynch event dispatch, which allows only one delegate
Steven A. Lowe
Steven: since every delegate is a multicast delegate, you just pile more delegates on the current event. should not be a problem. just another call target in the list.
Instead of creating all those anonymous delegates, just use an extension method to fire events and you only have one single place that checks if an event is null...myEvent.Fire(this, EventArgs.Empty);
Max Schmeling
public static class StringExt { public static bool IsNullOrEmpty( this String value ) { return String.IsNullOrEmpty(value); } public static bool IsEmpty( this String value ) { return value == String.Empty; }
Ruben Bartelink
Not sure if I like... off to look for an extension classes library... (a la Frans Bouma's post)
Ruben Bartelink
Beware using IsNullOrEmpty in VS2005 -
Richard Szalay
@Richard: This was fixed during CTP...
Erik Forbes
You are making an assumption with your event, you are not "making sure".Delegates are immutable, so every Delegate.Remove returns a new instance.And here's the deal: Calling Delegate.Remove on a Delegate with just that one last target method will yield ... *null*.How to get that target? The anonymous method does not capture locals/fields and thus will be static.So, doing this somewhere in your class should give you an NRE:MyASimpleEvent -= delegate{};This could be called from anywhere, only the EventHandler must be assigned in the same class.Don't like unproven assumptions. ;-)
Robert Giesecke
+60  A: 

System.Diagnostics.ConditionalAttribute. It makes the compiler ignore methods or classes that should only be active in certain build profiles. EG:

 private void DumpProperties()
     foreach (PropertyInfo prop in this.GetType().GetProperties())
         Console.WriteLine(prop.GetValue(this, null));
C. Lawrence Wenham
Just to clarify this: you can safely call (in the above example) DumpProperties() in both debug and release, but in release it just won't do anything.
Nice. I'll remember that one.
Is this the same as putting #ifdef DEBUG/#endif around the method contents?
Mark Pattison
Mark, as clarified by stusmith, no it is not the same. In release, it can still be called, it just won't do anything. The advantage here is that you don't need to wrap #ifdef DEBUG around the method AND the calling code, just decorate the method with the attribute. Very clean.
Matt Olenik
Just as a warning: if you call `Method(i++)` and the method is marked `[Conditional("DEBUG")]`, then the `i++` will be evaluated only in DEBUG mode, i.e. the variable `i` will have a different value depending on whether you’re in debug or release mode...
+135  A: 

Path class. I can't count the times the lack of its usage came up in code-reviews. People tend to go for the string concatenations and sub-stringage instead of using Path.Combine and Path.GetFileNameWithoutExtension, among others.

Doron Yaacoby
While I heartily agree, the Path class isn't actually a base class, is it?
Tor Haugen
@Tor - Path is in mscorlib.dll, so it is most definitely part of the BCL
Richard Szalay
You need to be careful with Path.Combine, if the second parameter starts with a "/", it may not do what you expect.
Noon Silk
The Path.Combine link has broken, it should point to
Stefan Monov
Also, what's so great about Path.Combine? Concatenation works fine for me.
Stefan Monov
@Stefan Monov: I just fixed the link.
+72  A: 

A cool way to log the name of the current method you're in:

string myMethodName = MethodBase.GetCurrentMethod().Name;

Bear in mind of course that the method you're in might be inlined.If you want to use the above method, mark your function as follows:[MethodImpl(MethodImplOptions.NoInlining)]
Am I sick because I see people who I admire in the community and enjoy the fact that my rep is higher than theirs? I think I need to see a shrink.
Yeah that definitely makes you sick. You should see a doctor about that.
does this work work where new StackTrace.GetFrame(1).getMethod fails because of optimizations?
so far it does, any idea what the syntax or namespace is for [MethodImpl(MethodImplOptions.NoInlining)] is in I'm not finding it
The method will NOT be inlined by the JIT, because it would change the behavior of the program.
Filip Navara
+5  A: 


I hate having to do interop, and particularly PInvoke, but there are all kinds of goodies in Marshal for turning function pointers into delegates, and vice versa, turning Win32 error codes into something a little more helpful (often only a little though), and so on.

Bart Read
+120  A: 

System.Security.SecureString - More people should be aware of this if their program accepts passwords or passphrases, or stores credit card numbers in memory. SecureString values are stored encrypted (obfuscated, rather), but most importantly, they are never swapped to disk and can be disposed of immediately when you're done with them.

They're tricky to use because you can only build them one character at a time (to encourage you to build them by capturing keystrokes as the user types their password), and require three lines of code to recover and then wipe their plain text, but when used properly they can make a program more secure by avoiding the virtual-memory vulnerability.

// Make a SecureString
SecureString sPassphrase = new SecureString();
Console.WriteLine("Please enter your passphrase");
ConsoleKeyInfo input = Console.ReadKey(true);
while (input.Key != ConsoleKey.Enter)
   input = Console.ReadKey(true);

// Recover plaintext from a SecureString
// Marshal is in the System.Runtime.InteropServices namespace
try {
   IntPtr ptrPassphrase = Marshal.SecureStringToBSTR(sPassphrase);
   string uPassphrase = Marshal.PtrToStringUni(ptrPassphrase);
   // ... use the string ...
catch {
   // error handling
finally {

Edit: At the end of the example the SecureString is converted into a regular managed string, which makes it vulnerable again (be sure to use the try-catch-finally pattern to Zero the string after you're done with it). SecureString's use is in reducing the surface-area of attack by limiting the number of copies the Garbage Collector will make of the value, and reducing the likelihood of being written to the swap file.

The .Net framework is gaining more support for SecureStrings that help eliminate the need to decrypt it. The PasswordBox control in WPF stores its value in a SecureString, System.Diagnostics.ProcessStartInfo's Password property takes a SecureString, and so does the constructor for X509Certificate2. Some third party components are beginning to take it as native currency, too.

C. Lawrence Wenham
That is a good one. I'll have to bring it up in the next dev meeting.
At the end, you have "uPassphrase", again unscrambled and unlocked in memory. What was the point again?
David Schmitt
David, you're right. I edited the answer to embellish on the correct use.
C. Lawrence Wenham
Wow, this can come in really handy. Thank you!
Wow, this seems pretty paranoid
Gurdas Nijor
Even with the edited answer, uPassphrase stays in memory unencrypted until the GC runs and it's overwritten with another new object.Due to the nature of the GC and managed memory, the only way to keep the string safe is to never put it in a System.String object.
+53  A: 

Most definitely String.Join(char separator, string[] list) to create "a,b,c" from {"a","b","c"}. This alleviates keeping track of a boolean to check whether the first item is already used.

I keep forgetting this exists. I see (and sometimes write) way too much code that does it the unnecessarily hard way.
Make it an extension method on IEnumerable<string> for bonus points
George Mauer
+19  A: 

The BitConverter.ToString method is very useful when working with binary data. I use it for debugging, traces and within unit testing.

It will take a byte array and return a printable string representation - something like "04-08-01-23-45-67-89-AB-CD-EF".

I also use Regex.Split(string, string) for splitting a delimited strings.

It is somewhat similar to String.Split(), but using Regex.Split() is much more intuitive: Regex.Split() result string array only contain the data you need, while String.Split() result also contains the delimiters.

String,Split removes the delimiters
Rune Grimstad
+10  A: 

System.Diagnostics namespace contains many "hidden" gems. I have used extensively the DebuggerStepThroughAttribute, I have subclassed many times the TraceListener class and I want to see in more detail the PerformanceCounter.

+37  A: 

System.Convert is a lot nicer than people think.

It's a bit more forgiving on what you put in. Use Reflector to see how it converts between different types.

Ints are defaulted to 0 from bad input, bools to false and so on.

It's made int.Parse, bool.Parse and all other .Parse almost obsolete for me. TryParse is still usefull for the most secure parsing.

Seb Nilsson
Thanks! This just saved me a heap of work.
Uhm what? System.Convert doesn't do that! It throws a FormatException generally speaking. There is one "gotcha", it *does* convert the null string into 0 - which, frankly, is a bug (MSDN sample code actually try..catches for a never-thrown ArgumentNullException, illustrating that the doc-writers themselves forget this gotcha...)
Eamon Nerbonne
+8  A: 

System.Linq is saving me a lot of time on Visual Studio 2008.

Jobi Joy
+4  A: 

System.Environment is one of my favorites. Especially the Workingset property.

+41  A: 

IEnumerable<T> isn't used nearly enough if you ask me.

Max Schmeling
I find IEnumerable<T> far more useful than arrays and lists. You can easily optimize for very large data sets without having to load everything into memory to work with it.
Great for searching through CSV files for one.
Max Schmeling
it's used everywhere in LINQ
Mark Cidade
I was gonna say: LINQ is a game-changer as far as IEnumerable<T> is concerned.
Robert Rossney
Don't forget IList<T> and ICollection<T>
Joel Coehoorn
In Haskell-speak, that's the "IEnumerable a" monad. SelectMany is a gamechanger as well - it's what happens when you use multiple from-clauses in linq.
Actually, LINQ uses IQueryable<T> everywhere, which implements IEnumerable<T>.
Daniel T.
@DanielT that's not exactly true. When doing simple LINQ2Objects all the methods you call are defined on IEnumerable<T>. I don't think IQueryable comes into play until you start using a LINQ provider
George Mauer
+30  A: 


Provides utility methods for common virtual path operations.

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)

    Dim sb As New StringBuilder()
    Dim pathstring As String = Context.Request.FilePath.ToString()
    sb.Append("Current file path = " & pathstring & "<br />")
    sb.Append("File name = " & VirtualPathUtility.GetFileName(pathstring).ToString() & "<br />")
    sb.Append("File extension = " & VirtualPathUtility.GetExtension(pathstring).ToString() & "<br />")
    sb.Append("Directory = " & VirtualPathUtility.GetDirectory(pathstring).ToString() & "<br />")

    Dim sb2 As New StringBuilder()
    Dim pathstring1 As String = Context.Request.CurrentExecutionFilePath.ToString()
    sb2.Append("Current Executing File Path = " & pathstring1.ToString() & "<br />")
    sb2.Append("Is Absolute = " & VirtualPathUtility.IsAbsolute(pathstring1).ToString() & "<br />")
    sb2.Append("Is AppRelative = " & VirtualPathUtility.IsAppRelative(pathstring1).ToString() & "<br />")
    sb2.Append("Make AppRelative = " & VirtualPathUtility.ToAppRelative(pathstring1).ToString() & "<br />")

End Sub
Chris Pietschmann
:o I have been looking for this for a loooong time! And all this time I've had to stick with Server.MapPath
+21  A: 

This is cool. VisualStyleInformation Class provides a lot of information about the current visual style of the operating system.

System.Diagnostics.Debugger.Break() is used by virtually everyone but is very convenient for debugging .NET services.

NetworkChange.NetworkAvailabilityChanged Event makes it easy to monitor network availability.

+7  A: 

If you are drawing custom Windows Forms controls, then the following classes are essential for your OnPaint() method (or Paint event):

using System.Windows.Forms;

These classes all provide methods that will do most of the drawing work for you and keep your controls looking professional and native.

+37  A: 

TextRenderer.MeasureText() is great for figuring out how large to draw your text. So often I see:

// this == something derived from Control
Graphics g = this.CreateGraphics();
Size size = g.MeasureString(this.Text, this.Font).ToSize();

When really all you need is:

Size size = TextRenderer.MeasureText(this.Text, this.Font);

The former is how you did it in 1.0 and 1.1; the latter is how you do it in 2.0+. It's much cleaner, doesn't requiring creating an object which must be disposed, and doesn't leave you open to accidentally not disposing of a resource. Plus if you use TextRenderer.DrawText() your text will look better and localize better. This stuff just plain rocks when you're doing custom controls.

Edit: On the I18N/G11N front, here's more info: the shaping engines for international text have been updated quite a bit in the Uniscribe subsystem of the Windows operating system, but not in GDI+ subsystem. So sometimes things looked strange/wrong if your .NET app was using the Graphics based method (AKA, GDI+). However, using the TextRenderer approach (AKA, Uniscribe) eliminates these problems and allows you to render text correctly (perfectly?) in the new locales introduced with Windows XP SP2 (such as Bengali and Croatian). (Caveat emptor: I have no idea how or even if either of these methods play with vendor specific extensions to specific code pages.)

Mike Post
Oh, where were you six months ago?
Robert Rossney
wish I could +10 this!
+2  A: 

For generating code files I like System.CodeDom.

+19  A: 

Here's a little snippet to tell which class/method the call is coming from. Useful in some special situations:

StackFrame frame = new StackFrame(1);
frame.GetMethod().Name; //Gets the current method name

MethodBase method = frame.GetMethod();
method.DeclaringType.Name //Gets the current class name
StackFrame and co are great for crawling up your stack to get the name of your test method for automatic intelligently named output.
Rick Minerich
Unfortunately because of the way optimizations work, this isn't reliable.
+10  A: 

String.Format(). Allows you to get rid of the wonkiness of "This" + " is" + " my favorite " + " Application";

If you're not using formatting, you should consider using String.Concat() - it's even faster!
Richard Szalay
Surprisingly, I just ran a benchmark and discovered there's almost no performance difference concatenating 8 strings of various sizes. Here are Stopwatch times; 10000 cycles for each method:(Ticks StringBuilder: 1382273472)(Ticks String.Concat: 1379808306)(Ticks String PlusOp: 1363064136)
how come there's no ticks for string.format in here?
The compiler will transform ("a" + 5) to String.Concat("a", 5).It will also transform ("a" + "b") to "ab".
+97  A: 


When you're debugging, if the class is attributed, visual studio will display the information on mouse-over. It even allows you to put in properties of private fields, etc.

[System.Diagnostics.DebuggerDisplay("MyClass: ID={ID} Name={Name} ChildName={_child.Name}")]

Ref: msdn

Robert Paulson
Cool. I'm shocked I didn't know or forgot about this useful attribute. Thanks!
You can customize it even further using the other properties on the DebuggerDisplay attribute.[DebuggerDisplay("Name = {Name}", Name="Alias #{AliasId}", Type="Person")]
I love this attribute
Can't you just implement ToString() in your class?
@Si, What if you use ToString() for something else? Besides - why clutter up your actual class-code with things that should only be available when debugging? An attribute is clear, the name says it all, it's decoupled from the class itself (sort of), and it looks cool. ;)
J. Steen
I wish standard C++ had this.
+3  A: 

I like to use System.Collections.CaseInsensitiveComparer to compare strings.

+26  A: 

TypeConverter class

It saved me a lot of time. And it helped Stack Overflow users to solve their problems:

Super useful class in certain situations. Back in v1.1 days I built a custom XML serialization engine (very narrow purposed) and TypeConverter ended up driving the conversion implementation of all but a few select types. Found the class using Reflector even.
+1  A: 
public static int Compare(string strA, string strB, bool ignoreCase)

Great to compare two strings with possible difference in letter case.

Dror Helper
+4  A: 

Gets the path (and name) of the current running application.

I have a few related commands at my Blog

Dror Helper
+17  A: 

I just found:


Used to encrypt data for the current user or the local machine.

Careful using this on webfarms, as this uses DPAPI. In other words the private key is stored in the user profile and that profile must be loaded prior to use. Also, loading profiles probably have an impact on memory utilization.
+6  A: 

Using StackFrame to get information about calling method and running class. You can travel the stack and get the methodName, calling calss etc. You can get the stackFrame using

StackFrame frame = new StackFrame(n);

Where n is the layer above the current call And then you can retrive information by using its properties. for example use the following the get the information of the calling method:

MethodBase methodBase = frame.GetMethod();
Dror Helper
+42  A: 

Represents a dynamic data collection that provides notifications when items get added, removed, or when the whole list is refreshed.

+52  A: 



These allow you to build a connection string in a programmatic way without have to remember the specific syntax.

Documentation: DbConnectionStringBuilder on MSDN

And when combined with a PropertyGrid it makes for powerful, but easily-programmed, database-agnostic connection setup forms. ;-)
+27  A: 

HashSet<T>. It is a new class in the .NET Framework 3.5 and is very similar to List<T> only better.

Jivko Petiov
That is a subjective statement. A HashSet cannot store two elements that are equivalent, and it does not guarantee an enumeration order. If you need either of those, or the ability to index into the collection, then you'd need to use a List of some sort.
Marcus Griep
HashSet is cool, but I wouldn't consider it at all similar to List ;)
No. It is not a replacement for List, it is a different data structure.
Matt Olenik
thumb down simply because the statement is incorrect. The term better is dependent on the context it is being used.
+27  A: 
.HashPasswordForStoringInConfigFile(string password, string format)

Does the simple and common task of getting the MD5 or SHA1 hash of a given string. Since almost every system I have ever written stored password hashes instead of encrypted data or the plaintext, this is a godsend to avoid mucking about with the Crypto stuff.

Nice one, I didn't know about that method ! Too bad its hidden in an ASP.NET specific namespace...
Thomas Levesque
+56  A: 

Using System.Environment.NewLine instead of "\r\n".

You meant, System.Enviroment.NewLine?
Erick Sgarbi
Fixed it for him
John Sheehan
when does this really matter beside of Mono ?
dr. evil
Highly underused. +1
@fm: Network-transmitted data? And Mono is quite a big part now (IMHO) of .NET development.
Lucas Jones
I was surprised to find that this didn't work inside of the .NET compact framework.
@Slapout, indeed, I was also very surprised and have to use "\r\n" anyway now everywhere.
Why would you use \r\n at all ever anyhow? Almost all applications are perfectly happy with just a \n, as far as I can tell...
Eamon Nerbonne
I was wondering why there isn't any VbCrLf substitute in C#. Thank you very much.
@Eamon Nerbonne: I take it you've never tried to open and re-save anything from Notepad where only \n was used. To paraphrase, I'd argue: Why would you use \n at all ever anyhow? Almost all applications are perfectly happy with just a \r\n, as far as I can tell...
+2  A: 

The DebuggerStepThroughAttribute is great for properties and also for those helper functions that you have no desire to step through. Unfortunately, it seems rarely known:

+24  A: 

Not really hidden but:

  • System.Drawing.Printing.PrinterSettings.InstalledPrinters: Returns a collection with all printer names installed in the machine.
Erick Sgarbi
Good find! I can definitely use this in one of our projects.
+67  A: 

Getting the list of countries. Useful for populating the drop down box.

foreach (CultureInfo ci in CultureInfo.GetCultures(CultureTypes.AllCultures & ~CultureTypes.NeutralCultures
       RegionInfo ri = new RegionInfo(ci.LCID);


Wow...this is built int! No more Googling for the list of countries!
Hm, your code throws for me. Despite the apparent intention to exclude neutral cultures, it nonetheless seems to get a neutral culture and then fails at the `RegionInfo` statement.
Interesting, but doesn't work.
Shawn Wildermuth
+1  A: 

Expanding the My Namespace has always been useful to me

Namespace My

    <Global.Microsoft.VisualBasic.HideModuleName()> _
    Friend Module MyStuff
        Sub Foo()

        End Sub
    End Module

End Namespace
John Chuckran
In what way has it been useful to you?
Peter Mortensen
+15  A: 

I'd have to say System.ComponentModel.BackgroundWorker.

It's not exactly easy to use, because you still have to understand how asynchronous method calls work, and you have to know about avoiding cross-thread exceptions, using Invoke to update the UI, etc. But it's considerably easier to use than System.Threading.Thread, which is what a lot of developers gravitate towards when they need to implement a background process.

Robert Rossney
+9  A: 

+9  A: 

More of a runtime feature, but I recently learned that there are two garbage collectors. The workstation gc and the server gc. Workstation is the default, but server is much faster on multicore machines.

      <gcServer enabled="true"/>

Be careful. The server gc requires more memory.

Mike Two
This is awesome news! Thx for that
Peter Gfader
That is awesome....never knew it existed.
David Andres
+6  A: 


This class is pretty esoteric and normally only used in weird remoting scenarios; however, I have used it for the ability to dynamically implement an interface. It is also used by some mocking frameworks for the same purpose. See also Extending RealProxy.

jon without an h
+13  A: 

Very helpful class to measure performance System.Diagnostics.StopWatch
See detailed posts here

+7  A: 

MatchEvaluator Delegate: Represents the method that is called each time a regular expression match is found during a Replace method operation.

John Sheehan
+20  A: 

You can play default windows sounds this way :

Sounds like fun! :)
Sandor Davidhazi
this rules and will get added to every application I write now :)
I found this useful for debugging timing/threading related code.
+3  A: 

In line with String.IsNullOrEmpty().....



string s = String.Empty;
string s = string.Empty;

instead of

string s = "";
public static readonly String Empty = "";:)
Chris S
+13  A: 

WeakReference. Extract from here ...

The garbage collector cannot collect an object in use by an application while the application's code can reach that object. The application is said to have a strong reference to the object.

A weak reference permits the garbage collector to collect the object while still allowing the application to access the object.

This can be used to implement weak events, see here

Deep comparison of XmlTrees


Compares the values of two nodes, including the values of all descendant nodes.

+18  A: 

Tired of typing the unwieldy

string.Equals(x, y, StringComparison.CurrentCultureIgnoreCase)


Instead, try one of the properties on the StringComparer class:

StringComparer Properties

Instead of the above, you can type:

StringComparer.CurrentCultureIgnoreCase.Equals(x, y);

Even though it's only slightly shorter, it's nice because it keeps the focus on the two things you're comparing, without the distraction of the StringComparison.CurrentCultureIgnoreCase parameter. And you can break it up if you like:

var comparer = StringComparer.CurrentCultureIgnoreCase;
comparer.Equals(x, y);
You should usually use `OrdinalIgnoreCase`
It entirely depends on what you're comparing and the reason for doing so.
+1  A: 

This isn't really a method but just something I found in the String class source:

// The Empty constant holds the empty string value.
// We need to call the String constructor so that the compiler doesn't mark this as a literal.
// Marking this as a literal would mean that it doesn't show up as a field which we can access 
// from native.
public static readonly String Empty = "";
Chris S
+4  A: 


Creates a new instance of a type without calling any constructor. This will work with private constructors, non-parameterless-constructors, any type of constructor (since they aint called).

I believe this is the only way to ensure that a static constructor on a type is executed if you only have a Type instance. (You can not invoke it with reflection, and the Activator may fail due to nonmatching constructors.)

A somewhat esoteric problem, and solution.

Simon Svensson
Actually, there's RuntimeHelpers.RunClassConstructor. See
Joe White
This is great for writting your own generic non-binary deserializer. The problem I had before I read your answer is that I was not able to create instances of types that do not have a public parameterless constructor. Thanks!
+1  A: 

Ignore Attribute on Unit-Tests for ignoring slow performance tests during development

Peter Gfader
+2  A: 

Decimal preserves trailing zeros :

decimal x = 1.0m;
decimal y = 1.00m;
decimal z = 1m;

Assert.IsTrue(x == y);
Assert.IsFalse(x.ToString() == y.ToString());

Assert.AreEqual("1.0", x.ToString(CultureInfo.InvariantCulture));
Assert.AreEqual("1.00", y.ToString(CultureInfo.InvariantCulture));
Assert.AreEqual("1", z.ToString(CultureInfo.InvariantCulture));

Assert.AreEqual("1.000", (x*y).ToString(CultureInfo.InvariantCulture));

This behavior is documented in the MSDN library.

The decimal.Parse method keeps track of trailing zeros too :

decimal x= decimal.Parse("1.0", CultureInfo.InvariantCulture);
decimal y= decimal.Parse("1.00", CultureInfo.InvariantCulture);

Assert.AreEqual("1.0", x.ToString(CultureInfo.InvariantCulture));
Assert.AreEqual("1.00", y.ToString(CultureInfo.InvariantCulture));
Think Before Coding
+1  A: 

Really useful class is System.Diagnostics.Stopwatch. It saves you from inventing a bicycle every time you need to measure time. It's really helpful when you need to make some time dependent work (perhaps periodic) in some thread.

Dmitry Lobanov
Already mentioned near the top.
+8  A: 

System.Net.Mail.MailAddress - no more regexp for server-side email address validation ;)

No TryParse method... so you have to catch the exception, which is not so good. I still prefer to use a regex...
Thomas Levesque
+6  A: 

I came across this today System.Data.SqlTypes.SqlDateTime

it has


among other methods & properties.

Nathan Koop
+8  A: 

Convert hexadecimal\octal\binary string to decimal:

Convert.ToInt32("2A", 16); // equals 42
Convert.ToInt32("52", 8); // equals 42
Convert.ToInt32("101010", 2); // equals 42

A great way to convert numbers to byte array:

byte[] bytes = BitConverter.GetBytes(32767);

Or better, use Jon Skeet's MiscUtil for endian bit conversion.

42, the answer to life, the universe, and everything.
Neil N
And the opposite : `Convert.ToString(42, 16)`. Interestingly, it works only for bases 2, 8, 10 and 16... other bases throw an exception. This is kind of strange, since the same implementation could support all bases up to 36 (at least).
Thomas Levesque
+3  A: 

Easy way of making an MD5 or SHA1 hash:

string hash = System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile("string to hash", "MD5");

Quick way of generating a unique, temporary file on disk:

string tempFilePath = System.IO.Path.GetTempFileName();

The System.Web.VirtualPathUtility class also has some interesting methods for manipulating file paths.

Parse an enum into a string array in one line (eg. get all known colours from KnowColor enumeration into an array):

string[] colours = System.Enum.GetNames(typeof(System.Drawing.KnownColor));

If you want to annoy your server admin when he's at the console, add this to your web app :D

Dan Diplo
+2  A: 


Escapes XML entities from a string so you can use it within an XML element. It's used by the framework in generation WS-Security XML, but saves four string replace statements in your own code.

+8  A: 

I use these built-in delegate types (and their "overloaded" cousins) all the time:

  • Func<T, TResult>
  • Action<T>
  • Predicate<T>

Along with Lambdas is C# 3.0 they're pretty useful and can help make things more readable. (You can of course still use them with C# 2.0 and anonymous delegates).

+22  A: 

Use this instead of concatenating the 2 strings yourself.

David Basarab
I used this everytime I am concatenating file paths since I found out about it
Another BCL that I've found to be a life-saver (even if not hidden) is System.Uri. I never realized the power of it until debugging an issue related to percent-encoding and had to really get under the hood.
It's not a straight concatenation... see:
+51  A: 

Use the


Don't do StartTime with DateTime, and then EndTime with DateTime.

See this answer.

David Basarab
I learned this one here :)
Just the clearify the answer. A DateTime value while having a 'ok' precision only gets updated about 10 times a second.The stopwatch class uses the 'system clock' for milliseconds precision. So the stopwatch is much better for high precision time measurements.
If you do need to use `DateTime.Now` in situations where performance is a concern then it's good to be aware of `DateTime.UtcNow` which is faster (it doesn't need to calculate local time)
Awesome! I've been looking for something like this.
+15  A: 

I don't think it's a hidden feature, but I don't see it used often:


Quite useful when you have a pile of accessor-type functions or something which you don't want to be stepping into while debugging.

I agree if it is used for accessor-type, but I have seen it abused, which hide bugs.
David Basarab
It's a great way to exclude methods from code-coverage results as well, but as David mentions it can be abused. Still, my jack-knife can be abused--but that doesn't make it a great tool!
[System.Diagnostics.DebuggerNonUserCode] is a better answer if you just want to step over some code. It can easily be disabled in the IDE via disabling Tools->Options->Debugging->Just my code
+7  A: 

Here's one, inspired by Marcc's related Diagnostics attribute:


It allows you to define the format of the string displayed in the Immediate / Locals window of Visual Studio, providing a string like "Person: {name} Cars: {cars.Count}" will display in the windows like "Person: John Doe Cars: 2".

This is handy. Failing this, you can also create a ToString() override.
This also allows you to stop non-Pure property getters (ones whose evaluation has side effects on program state) from altering program state due to implicit func eval.
+5  A: 

My favorite hidden feature is the SDK. OK, not very hidden, for some people, but most people seem to be able to develop .NET applications only with a tool or IDE, like Visual Studio. The SDK is free, and for small applications it's way quicker for me to write them up in emacs and then just build them with the command line compilers, csc.exe or vbc.exe.

Plus all the SDK tools are handy, too. XML Schema Definition Tool (xsd.exe), Strong Name Tool (sn.exe), and many others.

+6  A: 

TypeDescriptor when using Windows Forms data binding. This is how BindingSource can pretend to be any other object type.

you might have just answered a problem I've been having for a while... gotta go tinker with that!
Yeah, in playing with that I've managed to data bind nested properties using a custom type descriptor and custom property descriptors to flatten out the hierarchy. Also had an object that contains a collection of objects, then presents all the properties in those objects as a single object so you could do multi-row select in a grid to a single details view, and databind the details view normally.
it looks like the ITypedList interface is closely related; it's a little cludgy to implement but some examples out there show it doing some pretty slick stuff :)
+4  A: 

I found several cases where people were not aware of certain properties of the Environment class. In particular, I cleaned up several places in code and changed it to:

+20  A: 

String.Empty seems to be a hidden feature for many developers. String.IsNullOrEmpty(string) too.

... except that `string.Empty` is obsolete, and you should use `""` now (it’s more readable, too).
@Timwi Where have you read that String.Empty is obsolete? The MSDN does not say anything about that. It even does not say that one should use "" instead of String.Empty. And readability is a very personal factor.
@PVitt: Fair point. So let me change my comment. Now I would say: How is `string.Empty` a “hidden feature”? It’s completely useless, you can just write `""` instead. Why don’t we also have a `char.Space` for `' '` and an `int.Zero` for `0`? :-p
Because String.Empty is static. A comparison with "" always creates a new instance of string that is only used for the comparison. Thus leads to many useless objects spread out over the heap. On the other hand String.Empty as a static field is only instanciated once at a time und does not pollute the heap.
+3  A: 

The Managed, Native, and COM Interop Team at CodePlex have released a modified, open source TlbImp tool that allows simple creation of customized wrappers for pesky COM libraries.

+1  A: 

If you have a custom MSBuild task in your project that processes a file and subsequently creates .cs files to include in the same build, changes to the source file of the transformation often won't show in debugging without building twice. When you are generating a single file based solely on the content of a single source file, this task is best solved with a SingleFileGenerator. For multiple inputs and/or outputs, you may be stuck with an MSBuild task. In this case you can fix Visual Studio's dependency analysis by adding the following to your .csproj file:


It's introduces a few other annoyances, but it will allow you to have deterministic, correct single builds (a rather important goal).

+15  A: 
Do you have a bigger image?
Heh, I just forgot to link to it. Fixed now, thanks. :)
Wow! Thanks....................
+2  A: 

Despite being in the Microsoft.VisualBasic.dll assembly, this method can be called by C# just as easily and can quickly let you know if the object being tested can be evaluated as a number.

Related to it are the various TryParse() methods, which attempt to evaluate an object as a number but don't raise exceptions if the call fails... These can be found under a variety of different types such as System.Int32 and System.DateTime

You brought me back to my old VB6 days
yeah, the Microsoft.VisualBasic assembly can carry some old smells with it--but there's a few goodies that can make it worthwhile to keep in mind.
+6  A: 

If you're trying to convert between big/little endian then there is IPAddress.HostToNetworkOrder and IPAddress.NetworkToHostOrder. Why these methods were not part of the BitConverter class and in the obvious place people will look we'll never know.

But if you are on a big endian machine, HostToNetworkOrder would be BE->BE, no?
+2  A: 

[System.Diagnostics.ConditionalAttribute] - can be used instead of ugly preprocessor directives. For instance:

public void Validate()
    // ...
aesthetically it's better, but I'm not a big fan of having code being omitted from the compiled assembly. Just my $0.02
+7  A: 

I have to add Exception.GetBaseException(). I can't know how many times I've this code instead:

while(e.InnerException != null)
    e = e.InnerException;
return e.Message;

instead of just:

return e.GetBaseException().Message;
+1  A: 

The Action lambda is a delegate and hence gets the same delegate goodies that regular ones do - such as BeginInvoke():

new Action(() => MethodIWantToRunAsychronously())
  .BeginInvoke(new AsyncCallback(x => ThingToDoWhenMethodReturns()), null);

What it does: Spawns a new thread and runs MethodIWantToRunAsychronously() on it while your continuing to execute the current method on the current thread. When MethodIWantToRunAsychronously completes, ThingToDoWhenMethodReturns() is called (still) on the new thread.

George Mauer
Can you explain what the code does?
Peter Mortensen
It leaks memory. You **MUST** call `EndInvoke`. If you just want fire-and-forget, call `ThreadPool.QueueUserWorkItem(() => SomeMethod());`
Interesting SLaks. Had no idea.
George Mauer
re: ThreadPool.QueueUserWorkItem - this is used extensively in Monotouch apps to free the main thread while heavy crunching goes on in the bg. very useful
+1  A: 

FormatterServices.GetUninitializedObject Activator.CreateInstance

Has someone mentioned above two?

+4  A: 

Membership.GeneratePassword() (msdn) will generate a secure temporary password for you.

Gabe Moothart
+1  A: 

ToString() method of Object base class is really nice thing. Override it then bring mouse over instance variable in debug time after instance variable created. Don't even need DebuggerDisplay

class Program

    string name;
    string surname;
    static void Main(string[] args)
        Program instance = new Program() { name = "James", surname = "hetfield" };
    public override string ToString()
        return string.Format("name is {0}, surname is {1}",name,surname);
Ah thanks for editing. I forgot that ToString belongs to Object.
+6  A: 
string.Join([seperator], [array])

Couple this with LINQ and it rocks!

string.Join(",", customers.Select(c => c.Name).ToArray());

All your customer names in a CSV with one line of code :-)

To quote a certain internet reviewer, "I like it!"
In C# 4, string.join now accepts a IEnumerable<T>.
Pierre-Alain Vigeant
Just hope none of your Name properties have commas.
Joel Coehoorn
string.Join(",", customers.Select(c => string.Format("'{0}'",c.Name)).ToArray());
+4  A: 

System.Xml.XmlConvert contains lots of nice static methods to convert between XSD types and .Net types.