

where T : struct




Here are the revealed features so far:




Language Features

Visual Studio Features


Methods and Properties

Tips & Tricks

  • Nice method for event handlers by Andreas H.R. Nilsson
  • Uppercase comparisons by John
  • Access anonymous types without reflection by dp
  • A quick way to lazily instantiate collection properties by Will
  • JavaScript-like anonymous inline-functions by roosteronacid






Read more about locked posts here.

296 Answers 296


Many people don't realize that they can compare strings using: OrdinalIgnoreCase instead of having to do someString.ToUpper(). This removes the additional string allocation overhead.

if( myString.ToUpper() == theirString.ToUpper() ){ ... }


if( myString.Equals( theirString, StringComparison.OrdinalIgnoreCase ) ){ ... }
  • 39
    This could be changed quite easily to be null-safe as well: var isEqual = String.Equals(a, b, StringComparison.OrdinalIgnoreCase); – Robert Giesecke Aug 3 '09 at 12:03
  • But... this isn't a C# feature, it is a feature of the .Net framework, more specifically a feature of the class "String" – Jeroen Landheer Feb 1 '12 at 19:37

Just learned, anonymous types can infer property names from the variable name:

string hello = "world";
var o = new { hello };
  • this is because anonymous types are not anonymous after compilation. – codeSetter Dec 8 '11 at 22:00

Honestly the experts by the very definition should know this stuff. But to answer your question: Built-In Types Table (C# Reference)

The compiler flagging for numbers are widely known for these:

Decimal = M
Float = F
Double = D

// for example
double d = 30D;

However these are more obscure:

Long = L
Unsigned Long = UL
Unsigned Int = U
  • 4
    Every time I'm dealing with decimals, I have to look up the m. Is it only me or is m not really intuitive? :) – OregonGhost Mar 30 '09 at 10:56
  • 47
    The M syntax comes from the old VB type called Money. M == Money == Decimal. – Nick Berardi Mar 30 '09 at 19:46
  • 2
    is there one for byte? – Maslow Jun 26 '09 at 21:59
  • 3
    Nope, anything less than an Int32 is automatically inferred by the compiler based on the type to the left of it – Nick Berardi Jun 28 '09 at 10:59
  • 2
    @Nick: nice - I like learning the historicals behind the code. – IAbstract Jan 28 '10 at 6:24

I like looking up stuff in a list like:-

bool basketContainsFruit(string fruit) {
  return new[] { "apple", "orange", "banana", "pear" }.Contains(fruit);

Rather than:-

bool basketContainsFruit(string fruit) {
  return fruit == "apple" || fruit == "orange" || fruit == "banana" ||
    fruit == "pear";

Doesn't come up that much in practice, but the idea of matching items against the subject of the search can be really quite useful + succinct.

  • I'm curious what the compiler spits out for both implementations. The first one definitely looks cleaner and is a cute way of doing it. Could be slower though if the object is actually created in memory first then iterated through. – lc. Dec 13 '08 at 16:34
  • 7
    But you can have the best of both worlds (at least for this example, or for any integral type) using switch. Example follows, but readability suffers in comments due to lack of newlines: switch(fruit){ case "apple": case "orange": case "banana": case "pear": return true; default: return false; } – P Daddy Oct 10 '09 at 15:30
  • 2
    @P Daddy - true, but does suffer from a lot of additional syntax. @Fowl - you can have fallthrough if the cases have no code (until the fallen-through case of course). – ljs Jun 27 '10 at 22:27
  • 3
    public static bool In<T>(T value, params T[] items){ return items.Contains(value); } if (fruit.In("apple", "orange", "banana", "pear")) { ... } – John Gibb Apr 18 '11 at 17:50
  • 1
    @Belorus I think you're treating it as if readability were a science, which it is not. Yes, it is a performance hit, but very often it will make no difference to the overall performance of the program. How is it 'wrong' if it does the job, even if it needlessly allocates memory? Readability is a very subjective thing - what seems simple to one person can seem appalling to another. – ljs Aug 4 '11 at 8:20

InternalsVisibleTo attribute is one that is not that well known, but can come in increadibly handy in certain circumstances. It basically allows another assembly to be able to access "internal" elements of the defining assembly.

  • 12
    I use this regularly for writing unit tests against internal members of another assembly. That way unit tests can be excluded from deployments. – Drew Noakes Nov 20 '08 at 10:04
  • This is definitely my best discovery from this topic. The best solution I had found on my own to give unit tests in a different assembly access to internal methods was to make the methods protected and write pseudo-mock classes in my test assembly that inherited from the class being tested. – Mark Nelson May 20 '10 at 20:26
  • InternalsVisibleTo is very useful for exposing a protected internal parameterless .ctor to a NHibernate layer whilst hiding it from a user application which can then only use the public .ctor that enforces supplying required data. – Scott Rickman Dec 23 '11 at 13:48

Here is a new method of the string class in C# 4.0:

String.IsNullOrWhiteSpace(String value)

It's about time.

  • 3
    What's the problem with making your own util method that returns this: (myString ?? "").Trim() == "" – anonymous coward Jun 22 '10 at 5:10
  • 1
    @Charlie Isn't a carriage return treated as whitespace too? – MPritchard Jun 22 '10 at 6:53
  • 4
    I definitely prefer Haack's approach now that I have tried it out. You put together string extensions methods for AsNullIfEmpty and AsNullIfWhiteSpace. By doing it this way, you can then use the result in a coalescing operator: SomeString.AsNullIfEmpty() ?? "default value". – patridge Jun 22 '10 at 16:04
  • 2
    I really don't like "". You should use string.Empty (myString ?? string.Empty).Trim() == string.Empty as it conveys a bit more. – Dann Jun 30 '10 at 9:10
  • 3
    On the record, I absolutely HATE string.Empty. What could it ever be besides ""? The performance benefit of a static field vs an interned string will be negligible: stackoverflow.com/questions/263191/… – John Gibb Apr 18 '11 at 17:44

I picked this one up when using ReSharper:

Implicit Method Group Conversion

//If given this:
var myStrings = new List<string>(){"abc","def","xyz"};
//Then this:
myStrings.ForEach(s => Console.WriteLine(s));
//Is equivalent to this:

See "Implicit Method Group Conversion in C#" for more.

  • not for Debug.WriteLine though cuz it uses a #if DEBUG statement internally. – Henrik Feb 20 '09 at 6:48
  • @AndyC: It's not about that here (ForEach is simply defined as a custom extension method somewhere. There are religious debates over that elsewhere :)) – sehe Mar 23 '11 at 22:31
  • IMHO, the following looks better ----------------- foreach(string s in myString) Console.WriteLine(s); – Grigory Aug 3 '11 at 11:37

When debugging, you can type $exception in the Watch\QuickWatch\Immediate window and get all the info on the exception of the current frame. This is very useful if you've got 1st chance exceptions turned on!

  • TransactionScope and DependentTransaction in System.Transactions is a lightweight way to use transaction processing in .NET - it's not just for Database transactions either
  • String.IsNullOrEmpty is one that I am surprised to learn a lot of developers don't know about
  • List.ForEach - iterate through your generic list using a delegate method

There are more, but that is the three obvious ones of the top of my head...

  • I found that TransactionScope aggressively promotes transactions to distributed mode which uses DTC. When DTC becomes involved you'll probably have to deal with DCOM security. I tend to avoid the pain by using native transactions. – Hans Malherbe Jul 12 '09 at 18:27
  • 17
    That List.ForEach is faster than foreach or for(;;) is completely bonkers. ForEach uses a method/function delegate to implement the behavior. This is first of all, means worse cache locality because the code is generally executed further away (in memory) from the actual loop. Secondly all you really need to do to verify that this is slower is to look a the generated native code. There's a lot more stuff going on with List.ForEach than you might think. – John Leidegren Aug 5 '09 at 17:13
  • Completely bonkers? Well, I found .ForEach to be faster than all other options. See jerrytech.blogspot.com/2010/02/… if you doubt me. Always doubt me ;) The code's there - run it yourself and see. – Jerry Nixon - MSFT Sep 8 '10 at 22:28
  • On the other hand, Patrick Smacchia says the opposite: ForEach is slower than For. codebetter.com/blogs/patricksmacchia/archive/2008/11/19/… – James Sep 19 '10 at 20:04
  • 7
    There's now also String.IsNullOrWhitespace – Ray Feb 3 '11 at 11:53

Dictionary.TryGetValue(K key, out V value)

Works as a check and a get in one. Rather than;

    value = dictionary[key];

you can just do;

if(dictionary.TryGetValue(key, out value)) 
{ ... }

and the value has been set.

  • 19
    Another benefit of TryGetValue is that if your dictionary is synchronized, there is no race condition. Compared to ContainsKey where another thread could remove the item you are looking for between calls. – Guvante Oct 20 '08 at 19:12
  • 4
    TryGetValue throws if the key is null -- so much for avoiding axceptions. I use a TryGetValue2() extension method to get around this problem. – Qwertie Nov 6 '08 at 19:56
  • 3
    Looking up a null in a dictionary seems more likely a code error than looking up a non-existent value. I personally am glad that it throws the exception ;) – John Gibb Apr 18 '11 at 17:47

Conditional string.Format:

Applies different formatting to a number depending on whether the number is positive, negative, or zero.

string s = string.Format("{0:positive;negative;zero}", i);


string format = "000;-#;(0)";

string pos = 1.ToString(format);     // 001
string neg = (-1).ToString(format);  // -1
string zer = 0.ToString(format);     // (0)
  • 2
    This is similar to reg expressions, very useful, but I can't remember them either. I handle stuff like above with padleft and padright. – tuinstoel Aug 5 '09 at 17:25
  • Cool, I never knew it was possible... Is it documented anywhere ? – Thomas Levesque Aug 23 '09 at 11:18
  • @Thomas: It's documented in MSDN in the "The ";" Section Separator" section towards the end of the Custom Numeric Formatting topic at: msdn.microsoft.com/en-us/library/0c899ak8.aspx – devstuff Aug 23 '09 at 11:55

Events are really delegates under the hood and any delegate object can have multiple functions attached to it and detatched from it using the += and -= operators, respectively.

Events can also be controlled with the add/remove, similar to get/set except they're invoked when += and -= are used:

public event EventHandler SelectiveEvent(object sender, EventArgs args) 
  { add 
     { if (value.Target == null) throw new Exception("No static handlers!");
       _SelectiveEvent += value;
     { _SelectiveEvent -= value;
  } EventHandler _SelectiveEvent;

Don't forget about goto.

  • 55
    No, lets forget it. ;) – Gary Willoughby Nov 17 '08 at 10:57
  • 3
    No, lets abuse it till kingdom come. ;) – chakrit Dec 30 '08 at 18:47
  • 1
    Yeah, don't forget it--make sure to nuke it when you have a chance! – Loren Pechtel Jan 10 '10 at 2:50
  • 11
    +1. How do you break out from multiple levels of loops without messing with bool variables or moving the entire thing to a function or lambda? There should be a reason why does it exist in the language... – Calmarius Apr 10 '11 at 10:35
  • 1
    Two or three levels deep in nested loops and this is an absolute godsend. Can't think of any other possible legitimate reason to use it though. – tomfanning Aug 8 '11 at 23:20

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 on client versions of windows, but server is much faster on multicore machines.

      <gcServer enabled="true"/>

Be careful. The server gc requires more memory.

  • Nice tip. You should move this question to the Hidden .NET Base Class Library question stackoverflow.com/questions/122784/… – John Sheehan Oct 21 '08 at 19:10
  • Awesome. I've got a multicore webserver; its extra core and memory have been going to waste! – tsilb Nov 4 '08 at 23:37
  • This optimization works well for me on IronScheme too :) – leppie Dec 13 '08 at 22:22
  • 3
    On server SKUs of Windows (Server 2003, etc) the default is to use the server GC. The workstation GC is the default on client SKUs such as Vista. – DSO Jun 2 '09 at 21:11

Use "throw;" instead of "throw ex;" to preserve stack trace

If re-throwing an exception without adding additional information, use "throw" instead of "throw ex". An empty "throw" statement in a catch block will emit specific IL that re-throws the exception while preserving the original stack trace. "throw ex" loses the stack trace to the original source of the exception.


Other underused operators are checked and unchecked:

short x = 32767;   // 32767 is the max value for short
short y = 32767;
int z1 =  checked((short)(x + y));   //will throw an OverflowException
int z2 =  unchecked((short)(x + y)); // will return -2
int z3 =  (short)(x + y);            // will return -2
  • 6
    Instead of 32767 and a comment, how about short.MaxValue? – Clinton Pierce Apr 6 '10 at 19:15
  • 25
    Just reminding everyone what the exact MaxValue is! – Binoj Antony Apr 16 '10 at 11:24
  • perhaps we should list '32767' as the max value for a short as a hidden language feature of itself? (I think it is hidden programmer ethics to hardcode the number) – sehe Mar 23 '11 at 23:22

I couldn't see this looking above - one that I didn't realise you could do until recently is to call one constructor from another:

class Example
    public Example(int value1)
        : this(value1, "Default Value")

    public Example(int value1, string value2)
        m_Value1 = value1;
        m_value2 = value2;

    int m_Value1;
    string m_value2;
  • 1
    Although I used this thing cross classes, I never thought of using it in the same class. I have been looking all over the place for something like that! Great! – Boris Callens Nov 14 '08 at 1:16
  • That's great. I always used that calling the base, but never knew you could use it in the same class! – lc. Dec 13 '08 at 16:48
  • can you guys link to somewhere showing a usage example of this for cross class and base class? – Maslow Jul 8 '09 at 14:44
  • 3
    I think you meant: public Example(int value1) : this(value1, "Default Value") { } – rball Nov 11 '09 at 23:12
  • 1
    Well spotted rball! 1 year, 21 upvotes and nobody spotted my deliberate mistake ;) Fixed. – Grokys Nov 12 '09 at 1:53

A few hidden features I've come across:

  • stackalloc which lets you allocate arrays on the stack
  • Anonymous methods with no explicit parameter list, which are implicitly convertible to any delegate type with non-out/ref parameters (very handy for events, as noted in an earlier comment)
  • A lot of people aren't aware of what events really are (an add/remove pair of methods, like get/set for properties); field-like events in C# really declare both a variable and an event
  • The == and != operators can be overloaded to return types other than bool. Strange but true.
  • The query expression translation in C# 3 is really "simple" in some ways - which means you can get it to do some very odd things.
  • Nullable types have special boxing behaviour: a null value gets boxed to a null reference, and you can unbox from null to the nullable type too.
  • 1
    Unfortunately, stackalloc requires unsafe context. – RickNZ Dec 19 '09 at 4:46

I just wanted to copy that code without the comments. So, the trick is to simply press the Alt button, and then highlight the rectangle you like.(e. g. below).

protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
        //if (e.CommandName == "sel")
        //    lblCat.Text = e.CommandArgument.ToString();

In the above code if I want to select :

e.CommandName == "sel"

lblCat.Text = e.Comman

Then I press ALt key and select the rectangle and no need to uncomment the lines.

Check this out.

  • 2
    Interesting Visual Studio feature, but the question is about C#. – Fernando Nov 10 '09 at 12:15
  • 11
    +1 There is a section "Visual Studio Features" in this question, where your answer fits perfectly. – Roman Boiko Nov 24 '09 at 13:19
  • 1
    it is named virtual space. – Behrooz Feb 6 '10 at 14:31
  • 4
    It's not just Visual Studio feature. you can do this in Microsoft Word Notepad2 etc. etc. – chakrit Feb 25 '10 at 8:36
  • 13
    VS2010 lets you not only select, but edit text in this fashion - such as adding the word "private" to the beginning of every line simply by alt-selecting the space before the lines and starting to type - thereby correcting a poor practice of leaving off the word on multiple field declarations at the same time. – Matt DeKrey Jul 7 '10 at 1:40

@David in Dakota:

Console.WriteLine( "-".PadRight( 21, '-' ) );

I used to do this, until I discovered that the String class has a constructor that allows you to do the same thing in a cleaner way:

new String('-',22);
  • Why not do this Console.WriteLine( "".PadRight( 22, '-' ) ); – Jimmy Jun 3 '10 at 16:57
  • To achieve shorter and cleaner code, for example. – Konamiman Jun 4 '10 at 9:28

The volatile keyword to tell the compiler that a field can be modified by multiple threads concurrently.

  • 18
    Hey, this is not exactly true. The volatile keyword instructs the compiler to generate an acquire-fence on every read from a field, and a release-fence on every write to the field. An acquire-fence prevents other reads/writes from being moved before the fence; a release-fence prevents other reads/writes from being moved after the fence. Read more here: bit.ly/hycbVI – Anvaka Jan 8 '11 at 22:42

The params keyword, i.e.

public void DoSomething(params string[] theStrings)
  foreach(string s in theStrings)
    // Something with the Strings…

Called like

DoSomething(“The”, “cat”, “sat”, “on”, “the” ,”mat”);

A couple of things I like:

-If you create an interface similar to

 public interface SomeObject<T> where T : SomeObject<T>, new()

you force anything that inherits from this interface to contain a parameterless constructor. It is very useful for a couple of things I've run across.

-Using anonymous types to create a useful object on the fly:

var myAwesomeObject = new {Name="Foo", Size=10};

-Finally, many Java developers are familiar with syntax like:

public synchronized void MySynchronizedMethod(){}

However, in C# this is not valid syntax. The workaround is a method attribute:

 public void MySynchronizedMethod(){}
  • 2
    These are all good ideas. This site generally prefers one idea per answer so they can be rated individually. I would have given you three ratings :) – Drew Noakes Oct 11 '08 at 16:57
  • 7
    [MethodImpl(MethodImplOptions.Synchronized)] = lock(this) = bad – Greg Dean Oct 13 '08 at 3:34
  • I'm not familiar with "Sychronized" method, can you tell me what they do? – Matt Grande Mar 26 '09 at 13:10
  • 9
    "you force anything that inherits from this interface to contain a parameterless constructor" Strictly speaking, no you don't - you force any class that implements your interface to prove that it know the name of a class that implements the interface and has a parameterless constructor. That's not the same thing. class A : SomeObject<A> { public A() // required } class B : SomeObject<A> { } // will compile fine, no constructor. – James Hart Apr 29 '09 at 14:23
  • @Matt, in this case, synchronised (or the methodimpl attribute) locks on the current object while the method is processing. However, the attribute causes a lock(this) while it does it: and in CLR via C# I recall that this was not a good idea (iirc, it exposed a potential security vulnerability but the book is all the way on the other side of the house, and it's really late). This is why most people will lock on a private object member variable instead of lock(this). – Steven Evers Sep 3 '09 at 5:46

Foreach uses Duck Typing

Paraphrasing, or shamelessly stealing from Krzysztof Cwalinas blog on this. More interesting trivia than anything.

For your object to support foreach, you don't have to implement IEnumerable. I.e. this is not a constraint and it isn't checked by the compiler. What's checked is that

  • Your object provide a public method GetEnumerator that
    • takes no parameters
    • return a type that has two members
      1. a parameterless method MoveNext that returns a boolean
      2. a property Current with a getter that returns an Object

For example,

class Foo

    public struct Bar
        public bool MoveNext()
            return false;

        public object Current
            get { return null; }

// the following complies just fine:
Foo f = new Foo();
foreach (object o in f)
    Console.WriteLine("Krzysztof Cwalina's da man!");
  • 4
    That's awesome! I didn't knwo that... However, same thing with collection initializers... all you need is an Add(x) method. public class MyList{ public void Add(string s){} }. You can then do var l = new MyList{"a", "b", "c"};... – John Gibb Apr 18 '11 at 17:56
  • @JohnGibb: Having only an Add method is not sufficient. From section of the C# spec: "The collection object to which a collection initializer is applied must be of a type that implements System.Collections.IEnumerable or a compile-time error occurs." – Gabe Mar 8 '12 at 6:20

Static constructors.


public class Example
    static Example()
        // Code to execute during type initialization

    public Example()
        // Code to execute during object initialization

Static classes:

public static class Example
    static Example()
        // Code to execute during type initialization

MSDN says:


For example:

public class MyWebService
    public static DateTime StartTime;

    static MyWebService()
        MyWebService.StartTime = DateTime.Now;

    public TimeSpan Uptime
        get { return DateTime.Now - MyWebService.StartTime; }

But, you could also just as easily have done:

public class MyWebService
    public static DateTime StartTime = DateTime.Now;

    public TimeSpan Uptime
        get { return DateTime.Now - MyWebService.StartTime; }

So you'll be hard-pressed to find any instance when you actually need to use a static constructor.

MSDN offers useful notes on static constructors:


  • A static constructor is called automatically to initialize the class before the first instance is created
    or any static members are referenced.

  • A static constructor cannot be called directly.


    entries to this file.

  • Static constructors are also useful when creating wrapper classes for
    unmanaged code, when the constructor
    can call the LoadLibrary method.

  • If a static constructor throws an exception, the runtime will not
    lifetime of the application domain in which your program is running.

The most important note is that if an error occurs in the static constructor, a TypeIntializationException is thrown and you cannot drill down to the offending line of code. Instead, you have to examine the TypeInitializationException's InnerException member, which is the specific cause.

  • No need to lock as all the static members are thread safe. – NileshChauhan Mar 25 '09 at 12:34
  • Actually there was an internal web service that also could be used to change the value of connectionString too. So the lock was needed, no? I didn't remove the lock because I just copied the code and then added the comment. – core Mar 27 '09 at 6:02
  • Okay, I completely removed the example and made everything more clear (I hope!). – core Mar 27 '09 at 6:35
  • @nils_gate: No, that's a nasty mistake. You probably think this because MSDN docs often say "static members of SoAndSo class are thread safe." This is not because they're intrinsically thread safe. Quite the opposite, in fact. Since any thread can access static members without even having to share an object reference, then static members are more likely to find themselves in a race condition, which is why Microsoft has taken the trouble to make most of their static members thread safe. – P Daddy Jun 15 '09 at 2:08
  • &quotStatic constructors are also useful when creating wrapper classes for unmanaged code&quot, how about static destructor for unmanaged code? ;) – chapluck May 27 '10 at 13:31

A couple other attributes from the System.Diagnostics namespace are quite helpful.

DebuggerBrowsable will let you hide variables from the debugger window (we use it for all private backing variables of exposed properties). Along with that, DebuggerStepThrough makes the debugger step over that code, very useful for dumb properties (probably should be converted to auto-properties if you can take a dependency to the C# 3.0 compiler). As an example

private string nickName;
public string NickName    {
    get { return nickName; }
    set { this.nickName = value; }
  • 6
    Beware! DebuggerStepThrough is very handy, but should only be used on trivial implementations. When you are debugging, methods marked with this attribute are skipped entirely by the debugger as if they aren't there (which hides the implementation details from you as you will single step right past it). Breakpoints inside the method won't ever be triggered. – Jason Williams Aug 7 '09 at 5:58
  • 11
    Hmm...neat trick but I think I'd take fields being visible in the debugger over having all that cruft in my class – George Mauer Aug 31 '09 at 20:05
  • Plus if this causes you to miss even one bug ever, it won't have been worth your time. – BlueRaja - Danny Pflughoeft Apr 9 '10 at 13:19
  • the usefulness of [DebuggerBrowsable(DebuggerBrowsableState.Never)] is for long database calls for objects like users that have Invoices, Addresses, Phones, CreditCards, etc that are each calls to fill up via database calls. If anyone of these fails to return in time, the whole state of the object returned is unreadable (in the debugger). – Chuck Savage Apr 4 '11 at 22:48

C# + CLR:

  1. Thread.MemoryBarrier: Most people wouldn't have used it and there is some inaccurate information on MSDN. But if you know intricacies then you can do nifty lock-free synchronization.

  2. volatile, Thread.VolatileRead, Thread.VolatileWrite: There are very very few people who gets the use of these and even fewer who understands all the risks they avoid and introduce :).

  3. ThreadStatic variables: There was only one situation in past few years I've found that ThreadStatic variables were absolutely god send and indispensable. When you want to do something for entire call chain, for example, they are very useful.

  4. fixed keyword: It's a hidden weapon when you want to make access to elements of large array almost as fast as C++ (by default C# enforces bound checks that slows down things).

  5. default(typeName) keyword can be used outside of generic class as well. It's useful to create empty copy of struct.

  6. One of the handy feature I use is DataRow[columnName].ToString() always returns non-null value. If value in database was NULL, you get empty string.

  7. Use Debugger object to break automatically when you want developer's attention even if s/he hasn't enabled automatic break on exception:

#if DEBUG  
    if (Debugger.IsAttached)  
  1. You can alias complicated ugly looking generic types so you don't have to copy paste them again and again. Also you can make changes to that type in one place. For example,

    using ComplicatedDictionary = Dictionary<int, Dictionary<string, object>>;
    ComplicatedDictionary myDictionary = new ComplicatedDictionary();
  • Sweet, great tips, in the last one you had tag trouble... replace < with &lt; and we will be able to read it :) – Cohen Nov 10 '09 at 19:28
  • Now most of this comes down to 'people don't know the mechanics behind threading' IMHO. That may be true, but doesn't come close to 'hidden language features'? Thumbs up for Debugger.Break() – sehe Mar 23 '11 at 23:08


Since anonymous delegates were added to 2.0, we have been able to develop closures. They are rarely used by programmers but provide great benefits such as immediate code reuse. Consider this piece of code:

bool changed = false;

if (model.Prop1 != prop1)
    changed = true;
    model.Prop1 = prop1;
if (model.Prop2 != prop2)
    changed = true;
    model.Prop2 = prop2;
// ... etc. 

Note that the if-statements above perform similar pieces of code with the exception of one line of code, i.e. setting different properties. This can be shortened with the following, where the varying line of code is entered as a parameter to an Action object, appropriately named setAndTagChanged:

bool changed = false;
Action<Action> setAndTagChanged = (action) => 
    changed = true; 

if (model.Prop1 != prop1) setAndTagChanged(() => model.Prop1 = prop1);
if (model.Prop2 != prop2) setAndTagChanged(() => model.Prop2 = prop2);

In the second case, the closure allows you to scope the change variable in your lambda, which is a concise way to approach this problem.

An alternate way is to use another unused feature, the "or equal" binary assignment operator. The following code shows how:

private bool conditionalSet(bool condition, Action action)
    if (condition) action();
    return condition;

// ...

bool changed = false;
changed |= conditionalSet(model.Prop1 == prop1, () => model.Prop1 = prop1);
changed |= conditionalSet(model.Prop2 == prop2, () => model.Prop2 = prop2);
  • I'm not having any luck getting the 2nd one to compile? is it .net 3.5 only? public int eye { get; set; } private void testClosure() { var i = 0; bool changed = false; Action<Action> setAndTagChanged = (action) => { changed = true; action(); }; setAndTagChanged(eye=1); } – Maslow Jun 26 '09 at 21:20
  • Lambdas are only available in C# 3.0 or greater. That means you must have .Net 3.5. – Michael Meadows Jun 29 '09 at 13:34
  • Thanks, luckily we've moved up to .net 3.5 thanks to my pushing for it – Maslow Aug 14 '09 at 19:07
  • +1 Link to closures question:stackoverflow.com/questions/428617/closures-in-net Article with explanation of compiler generated code blogs.msdn.com/b/abhinaba/archive/2005/10/18/482180.aspx – chapluck May 27 '10 at 14:12

I'd say using certain system classes for extension methods is very handy, for example System.Enum, you can do something like below...

public enum ErrorTypes : int {
    None = 0,
    MissingPassword = 1,
    MissingUsername = 2,
    PasswordIncorrect = 4

public static class EnumExtensions {

    public static T Append<T> (this System.Enum type, T value) where T : struct
        return (T)(ValueType)(((int)(ValueType) type | (int)(ValueType) value));

    public static T Remove<T> (this System.Enum type, T value) where T : struct
        return (T)(ValueType)(((int)(ValueType)type & ~(int)(ValueType)value));

    public static bool Has<T> (this System.Enum type, T value) where T : struct
        return (((int)(ValueType)type & (int)(ValueType)value) == (int)(ValueType)value);



//used like the following...

ErrorTypes error = ErrorTypes.None;
error = error.Append(ErrorTypes.MissingUsername);
error = error.Append(ErrorTypes.MissingPassword);
error = error.Remove(ErrorTypes.MissingUsername);

//then you can check using other methods
if (error.Has(ErrorTypes.MissingUsername)) {

This is just an example of course - the methods could use a little more work...

  • 1
    Nice; but I'd use Include instead of Append since Append implies an order which the values may not have. – devstuff Aug 23 '09 at 12:16
  • @devstuff - that is a good point, I didn't really ever think about it from that perspective. – Hugoware Aug 23 '09 at 23:05
  • @HBoss: I'm gonna use that. It will make it so much easier to implement Flags the way we should be. – IAbstract Jan 28 '10 at 6:44
  • Just figured something awesome out: All those "object" casts are causing a lot of boxing. If you add a generic constraint of where T : struct (so that T can't be a reference type), you can actually cast (int)(ValueType)value and avoid the boxing: I've edited the answer to show this. – John Gibb Apr 18 '11 at 18:13

Being able to have enum types have values other than int (the default)

public enum MyEnum : long
    Val1 = 1,
    Val2 = 2

Also, the fact that you can assign any numeric value to that enum:

MyEnum e = (MyEnum)123;
  • But the values have to be discreet. So no floats or doubles etc. Just for completeness' sake ;) – Boris Callens Sep 23 '08 at 7:24
  • 3
    Why would you want to be able to assign just any old value to an enum? Isn't the point of an enum to limit the choices of values? – RobH May 8 '09 at 18:51
  • 4
    I believe the compiler has to support this for the sake of supporting flags. So given the enum above, if you do MyEnum val = MyEnum.Val1 | MyEnum.Val2 you would end up with a value that is outside of the already defined possible values. (in this case 3). Since you can do binary arithmetic on enums they can theoretically have many possible values. – Luke Foust May 11 '09 at 21:35
  • 1
    One good reason would be to match it to the ID column of a read-only bootstrap table in a database. – Aaronaught Dec 17 '09 at 21:59
  • 4
    You can also have [Flags] to tell that the enum is flag based – SztupY May 16 '10 at 11:33
