I like resource files. I can put all the strings that are displayed to the user in my application into one easily modified resource file. How many times do you demo an application and the customer says: "can you change this message to say X instead"; or worse: "There's a typo in this text." Customers often have long lists of these sorts of minor changes to the text of an application. Instead of using search and replace, which can involve touching many different pieces of the application (and trigger a new round of unit and/or acceptance testing) if you've used a resource file to store these strings you can make all the modifications in one place without impacting any source code -- sort of like a configuration file for application constants. The kicker is you can compile alternate versions of the "constant files" and substitute them into your application without having to recompile the whole thing. MSDN has the steps on how to create a "resource assembly" as this compiled external resource file is known.
If you're just getting started with resource files, it's easy. Add a file of type "resx" to your VS.Net project (in the New File dialog box for VS.Net it's under Add->New Item->Resources->Assembly Resource file. VS.Net presents the resx file in Data or XML view, the Data view is easiest for entering simple strings of text. The "Name" column is the "Key" with which you'll lookup your strings; the "Value" column is the string associated with the key. This tabular view in VS.Net makes working with these strings a breeze.
Once you've got a test string in there, your code can access the strings by creating an instance of the ResourceManager type (add a reference to System.Resources):
static ResourceManager resMgr =
new ResourceManager( typeof( myClass ).Namespace + ".ResourceFileName",
Assembly.GetAssembly( typeof( myClass ) ) ) ;
Note that this constructor takes two arguments: the name of the resource file (like Namespace.Class) and the assembly containing the resource file. I'm using a little Reflection to dynamically determine the assembly name, but you could hardcode it, just be sure to reference the System.Reflection namespace to access the Assembly object from your code.
In your code, to access a specific value from the resource file use:
resMgr.GetString( "MyKey" )
You'll want to replace "MyKey" with the key in your resource file. Now you can have your validation messages, exception handling text, etc all originate from a single resource file for ease of maintenance and sanity when it comes time to update or modify the text. No more "magic strings" baked into the fabric of your code -- and for real decoupling of these resource files from your code, check out the Resource Assembly approach I referenced earlier. Critics may point out that the “Key“ of the Resource item is a form of baked-in string for your application -- but it's one that you will never have to change and never is displayed to a customer, so in my opinion, that sort of baking is acceptable.
This should be enough to get you started with Resources. I will often create the ResourceManager in a base class so that I only have the ResourceManager declaration code etc in one spot in the project. For example, I will derive every page in an ASPX applications from a custom page object (which inherits from the System.Web.UI.Page class), and this ResourceManager approach fits in well in that base class scenario.