Click here to Skip to main content
15,881,600 members
Please Sign up or sign in to vote.
2.00/5 (2 votes)
See more:
Hi all,

So frustrated. I did two days' research, and I do not know how to localize a constant string. Could you help? My thing is: I can declare a local constant string, but it can not be accessed from other class. I cannot declare the constant string before the method, because I need the method to accept the parameters such as en-GB,fr-FR to specify the resource files. Please help. Thanks in advance.

I have a this code in one of the classes: private const string Header = "Phone Number";
private string Footer = "Name";
I want to localize it, so I have a Localization class:
namespace People
{
    public static class Localization
    {
        public static string Name = null;// For name, it all works, because Name is private string
        public static string Phone_Number = null; // For Phone_Number, it doesn't, because Phone_Number is a constant string

        public static void CultureInput(String culture)
        {
            CultureInfo ci = new CultureInfo(culture);
            ResourceManager resourceMgr = ResourceManager.CreateFileBasedResourceManager(...);
            Name = resourceMgr.GetString("Name", ci);
            Phone_Number = resourceMgr.GetString("Phone_Number ", ci); 
            }
        }
}

When I try to replace: private const string Header = Localization.Phone_Number;
It gives me an error: Header must be assigned a constant.


[Edited]Code is wrapped in "pre" tag[/Edited]
Posted
Updated 27-Sep-11 4:42am
v3
Comments
André Kraak 27-Sep-11 10:21am    
Please share any relevant code with us, seeing the code might us help understand the problem you are facing.

If you wish to change your question use the Improve Question button.

Don't use a constant string for localization, use a static string property that pulls your localized string values from resources.
 
Share this answer
 
Comments
Member 8256632 27-Sep-11 10:42am    
yes, I did not. But the code I want to localize includes a constant string.
fjdiewornncalwe 27-Sep-11 10:45am    
Then you should convert that constant into a static property or something of that nature. At that point you can localize it. Using a static string or a constant string from a consumer perspective is exactly the same so the conversion can happen if necessary.
Sergey Alexandrovich Kryukov 27-Sep-11 10:58am    
Well, stop using this constant string. I provided enough detail in my solution.
Ask if you have a further question.
--SA
Sergey Alexandrovich Kryukov 27-Sep-11 10:59am    
That is correct, but see how much detail I put in my solution to express this simple idea :-)
Actually, I knew how many misconception is there about localization and put some key idea in bold, please see. :-)
--SA
Member 8256632 27-Sep-11 11:10am    
Thank you. I appreciate. Because this is my first time using c#. So Some simple ideas for me are not simple, I really thank you guys for the patience.
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:

C#
const string endPointAddressFormat = "https://www.myDomain.tld/myService&username={0}"; //explicit constant

//also constant by its semantic, but a function call requires a static field
static string endPointAddress = string.Format(endPointAddressFormat, "me");

const string exceptionFormat = @"{0}: {1}"; //another explicit constant

string message = "Does not work!"; //message is a variable, "Does not work!" is immediate constant -- VERY BAD PRACTICE
string betterMessage = string.Format(exceptionFormat, myException.GetType().Name, myException.Message); //MUCH better

//but moving exceptionFormat to resource would be the best


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
 
Share this answer
 
v7
Comments
Member 8256632 27-Sep-11 12:02pm    
"it will be placed as a child node of the resource node."

I do it manually? Resource node is resource.resx or the Resource Folder in visual studio 2008? Thanks.
Member 8256632 27-Sep-11 13:10pm    
I find. I start over everything, and find there is a .cs file. I do not know why the first time I create xxx.en-GB.resx this resource file, there is no a c# file. strange.
Member 8256632 27-Sep-11 13:13pm    
Please tell me how to "get rid of all immediate constants (those hard-coded in your code)"? I just remove them to the resource file or remove them from the source code (somebody else write it)? Please.
fjdiewornncalwe 27-Sep-11 14:34pm    
Remove the constant keyword from them and make them work the same way as existing strings that you have already converted to use resources.
Sergey Alexandrovich Kryukov 27-Sep-11 20:31pm    
No, no, the question was about immediate constants. They have to go first, sometimes converted to explicit constant. I'll have to explain...
--SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900