By definition,
you cannot localize a constant. (A
constant is so constant, isn't it? :-))
Before localization, you need to
globalize the project. Basically, it means making the project
functionality agnostic to the UI culture.
First, you need to get rid of all
immediate constants (those hard-coded in your code), especially strings. For an intermediate step, you can turn them into constants explicitly defined in some (special) static class. In some projects there can be some constants that should never be localized anyway (but not always); in this case, mark this part of code clearly: "do not localize".
When you see what strings to localize, move them all to the resources. Let's assume you use .resx resources. Create a resource file, add resource names and values. Now, open the auto-generated C# file; in project structure presented in Solution Explorer, it will be placed as a child node of the resource node. In this file, locate a static class with static properties; the name of the properties will be the same or resembling your names in the resource file. Now, simply use these names instead of constants in your code. As a result, all immediate constants should go, and all of the constants subject to localization are found in resources only.
Actually, there are more to globalization, but the step described above is the most important. You also need to make sure that your UI design can behave nicely when the lengths of all rendered strings change. You also should take care of correct and culture-independent processing of all kinds of data depending on culture, such as date-time formats, currency, presentation of numbers and the like. During localization, you will need to decide what to do with all the keyboard
hot keys and test them for consistency.
Globalization is done, time to go to localization. For localization, you should never re-touch or modify your base globalized code.
The main globalized assemblies remains the same during localization. The is the key idea of localization. Localized resource are added to solution, not replacing anything. The application should only be able to switch thread's culture and UI culture.
Create
satellite assemblies matching the structure of your globalized resources. Your build should place them in separate directories according to naming conventions for the cultures. When a culture of the application's thread (let's say, a main UI thread) is switches to a different one, the globalized application automatically selects the set of resources to be used. The resource assemblies (satellite assemblies) are found by a culture name (like fr-FR) in respective resource directory; if such directory is not found, the
callback mechanism finds the nearest available implemented culture all the way down to the culture used in main globalized assemblies, in case no localized resource can be found.
For further information, see:
http://msdn.microsoft.com/en-us/library/21a15yht%28v=VS.100%29.aspx[
^].
[EDIT]
This is some clarification about constants, in response to discussion found below:
const string endPointAddressFormat = "https://www.myDomain.tld/myService&username={0}";
static string endPointAddress = string.Format(endPointAddressFormat, "me");
const string exceptionFormat = @"{0}: {1}";
string message = "Does not work!";
string betterMessage = string.Format(exceptionFormat, myException.GetType().Name, myException.Message);
Immediate constants is bad even if it should not be localized. They turn maintenance into nightmare. They are acceptable and convenient only during development. How about explicit constants? It depends. Many should be moved to configuration data files or resources, but some are just fine.
—SA