Just sharing some of my inconsequential lunch conversations with you... RSS  

Monday, January 21, 2008

C#: the difference between const and static readonly

Here's a question that pops out every now and then. The biggest of the differences is that const is defined at compile time, as readonly is defined at runtime - limited to initialization and constructors. And both of them cannot be changed at runtime. Here's a sample:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication6
{
class Program
{
const int myConst1 = 1;
const int myConst2 = 2;
#if false
const int myConst = DateTime.Now.Second; // illegal
#endif
static readonly int myReadOnly = DateTime.Now.Second;

static void Main(string[] args)
{
#if false
myReadOnly = DateTime.Now.Second; // illegal,
#endif

switch (myReadOnly)
{
case myConst1:
Console.WriteLine("myConst1: {0}", myConst1);
break;

case myConst2:
Console.WriteLine("myConst2: {0}", myConst2);
break;

// case myReadOnly: ; // illegal on a switch
// break;
}

Console.WriteLine("myReadOnly: {0}", myReadOnly);
}
}
}

And here's the code re-engineered back from IL through Lutz Roeder's Reflector:

private static void Main(string[] args)
{
switch (myReadOnly)
{
case 1:
Console.WriteLine("myConst1: {0}", 1);
break;

case 2:
Console.WriteLine("myConst2: {0}", 2);
break;
}
Console.WriteLine("myReadOnly: {0}", myReadOnly);
}

And naturally:

static Program()
{
myReadOnly = DateTime.Now.Second;
}

There are some hints that may seem natural from this, like:

  1. if you need to port from C #define, use const;

  2. if you need to use switch, use const;

  3. If you want to guarantee a value type will never change, use const;

  4. If you are some paranoid needs of performance, or don't want to waste unnecessary memory, use const;

  5. If you need to set a value at runtime only for the first time, either because it is not a const, or because it depends on a constructor, use readonly;

  6. If you want a reference type other then string, use readonly;

  7. if you need to decouple constants on an assembly to another assembly, use readonly - but then it wouldn't really be a const, would it? More like a preset.

No comments:

Development Catharsis :: Copyright 2006 Mário Romano