C# 6 and .NET Core 1.0:Modern Cross:Platform Development
上QQ阅读APP看书,第一时间看更新

Internationalizing an application

Internationalization is the process of enabling your application to run correctly all over the world. It has two parts: globalization and localization.

Globalization is about writing your code to accommodate multiple languages and regions. The combination of a language and a region is known as a culture. It is important for your code to know both the language and region because date and currency formats are different in Quebec and Paris despite them both using French.

There are International Standards Organization (ISO) codes for all culture combinations. For example, in the code da-DK, da indicates the Danish language and DK indicates the country of Denmark.

Localization is about customizing the user interface to support a particular language. Since localization is just about the language, it doesn't need to know about the region.

Internationalization is a huge topic that entire books have been written about. In this section, you will get a brief introduction to the basics using the CultureInfo type in the System.Globalization namespace.

Tip

.NET Core 1.0 does not currently allow threads to get or set their CurrentCulture or CurrentUICulture properties. An alternative for getting these two properties (but not setting) is to use the CultureInfo class's static properties, but you cannot set them.

Globalizing an application

Add a new console application project named Ch05_Internationalization. At the top of the file, import the following types and namespaces:

using static System.Console;
using System;
using System.Threading;
using System.Globalization;

In the Main method, enter the following statements:

Thread t = Thread.CurrentThread;
WriteLine($"The current globalization culture is {t.CurrentCulture.Name}: {t.CurrentCulture.DisplayName}");
WriteLine($"The current localization culture is {t.CurrentUICulture.Name}: {t.CurrentUICulture.DisplayName}");
WriteLine();
WriteLine("en-US: English (United States)");
WriteLine("da-DK: Danish (Denmark)");
WriteLine("fr-CA: French (Canada)");
Write("Enter an ISO culture code: ");
string newculture = ReadLine();
if(!string.IsNullOrEmpty(newculture))
{
    var ci = new CultureInfo(newculture);
    Thread.CurrentThread.CurrentCulture = ci;
    Thread.CurrentThread.CurrentUICulture = ci;
}
Write("Enter your name: ");
string name = ReadLine();
Write("Enter your date of birth: ");
string dob = ReadLine();
Write("Enter your salary: ");
string salary = ReadLine();
DateTime date = DateTime.Parse(dob);
int minutes = (int)DateTime.Today.Subtract(date).TotalMinutes;
decimal earns = decimal.Parse(salary);
WriteLine($"{name} was born on a {date:dddd} and is {minutes:N0} minutes old and earns {earns:C}.");

When you run an application, it automatically sets its thread to use the culture of the operating system. I am running my code in London, UK, so the thread is already set to English (United Kingdom).

The code prompts the user to enter an alternative ISO code. This allows your applications to replace the default culture at runtime.

The application then uses standard format codes to output the day of the week dddd, the number of minutes with thousand separators N0, and the salary with the currency symbol C. These adapt automatically based on the thread's culture.

Press Ctrl + F5. Enter en-GB for the ISO code and then enter some sample data. You will need to enter a date in a format valid for British English:

Enter an ISO culture code: en-GB
Enter your name: Alice
Enter your date of birth: 30/3/1967
Enter your salary: 23500
Alice was born on a Thursday, is 25,469,280 minutes old and earns £23,500.00.

Rerun the application and try a different culture such as Danish in Denmark (da-DK). You will need to enter a date in a format valid for the culture you chose:

Enter an ISO culture code: da-DK
Enter your name: Mikkel
Enter your date of birth: 12.3.1980
Enter your salary: 34000
Mikkel was born on a onsdag, is 18.656.640 minutes old and earns kr. 34.000,00.

Localizing an application

The application does not currently change the prompts. They have been hardcoded to always ask in English. We can improve this using localization. Choose Project | Add New Item… or press Ctrl + Shift + A.

In the dialog box, type resource into the search box, change the name of the resources file that you are adding to Prompts.resx, and then click on Add:

Add the following entries and then close the resource editor:

In the Solution Explorer window, copy and paste the Prompts.resx file by selecting it and pressing Ctrl + C and then Ctrl + V.

Rename the new copy to Prompts.fr.resx. The fr indicates that this new copy should be used for French. Open it and modify the entry values as follows:

Modify the following statements in the Main method:

Write($"{Prompts.EnterYourName} ");
string name = ReadLine();
Write($"{Prompts.EnterYourDOB} ");
string dob = ReadLine();
Write($"{Prompts.EnterYourSalary} ");
string salary = ReadLine();

Press Ctrl + F5. With an ISO culture code of fr-FR, this will load the French prompts:

Enter an ISO culture code: fr-FR
Entrez votre nom: Michel
Entrez votre date de naissance: 4 5 1967
Entrez votre salaire: 72000
Michel was born on a jeudi, is 25 418 880 minutes old and earns 72 000,00 ?.

With any other ISO code, it will load English prompts (think of a resource file without an ISO code in its name as being the default). You could use Microsoft Bing or Google Translate to create your resource files.

Tip

Best Practice

Consider whether your application needs to be internationalized and plan for that before you start coding! Write down all the pieces of text in the user interface that will need to be localized. Think about all the data that will need to be globalized (date formats, number formats, and sorting text behavior).