Next: , Previous: Java, Up: List of Programming Languages   [Contents][Index]


15.5.12 C#

RPMs

pnet, pnetlib 0.6.2 or newer, or mono 0.29 or newer

File extension

cs

String syntax

"abc", @"abc"

gettext shorthand

_("abc")

gettext/ngettext functions

GettextResourceManager.GetString, GettextResourceManager.GetPluralString GettextResourceManager.GetParticularString GettextResourceManager.GetParticularPluralString

textdomain

new GettextResourceManager(domain)

bindtextdomain

—, compiled message catalogs are located in subdirectories of the directory containing the executable

setlocale

automatic

Prerequisite

Use or emulate GNU gettext

—, uses a C# specific message catalog format

Extractor

xgettext -k_

Formatting with positions

String.Format "{1} {0}"

Portability

fully portable

po-mode marking

Before marking strings as internationalizable, uses of the string concatenation operator need to be converted to String.Format invocations. For example, "file "+filename+" not found" becomes String.Format("file {0} not found", filename). Only after this is done, can the strings be marked and extracted.

GNU gettext uses the native C#/.NET internationalization mechanism, namely the classes ResourceManager and ResourceSet. Applications use the ResourceManager methods to retrieve the native language translation of strings. An instance of ResourceSet is the in-memory representation of a message catalog file. The ResourceManager loads and accesses ResourceSet instances as needed to look up the translations.

There are two formats of ResourceSets that can be directly loaded by the C# runtime: .resources files and .dll files.

Note that these .NET .dll and .exe files are not tied to a particular platform; their file format and GNU gettext for C# can be used on any platform.

To convert a PO file to a .resources file, the msgfmt program can be used with the option ‘--csharp-resources’. To convert a .resources file back to a PO file, the msgunfmt program can be used with the option ‘--csharp-resources’. You can also, in some cases, use the resgen program (from the pnet package) or the monoresgen program (from the mono/mcs package). These programs can also convert a .resources file back to a PO file. But beware: as of this writing (January 2004), the monoresgen converter is quite buggy and the resgen converter ignores the encoding of the PO files.

To convert a PO file to a .dll file, the msgfmt program can be used with the option --csharp. The result will be a .dll file containing a subclass of GettextResourceSet, which itself is a subclass of ResourceSet. To convert a .dll file containing a GettextResourceSet subclass back to a PO file, the msgunfmt program can be used with the option --csharp.

The advantages of the .dll format over the .resources format are:

  1. Freedom to localize: Users can add their own translations to an application after it has been built and distributed. Whereas when the programmer uses a ResourceManager constructor provided by the system, the set of .resources files for an application must be specified when the application is built and cannot be extended afterwards.
  2. Plural handling: A message catalog in .dll format supports the plural handling function GetPluralString. Whereas .resources files can only contain data and only support lookups that depend on a single string.
  3. Context handling: A message catalog in .dll format supports the query-with-context functions GetParticularString and GetParticularPluralString. Whereas .resources files can only contain data and only support lookups that depend on a single string.
  4. The GettextResourceManager that loads the message catalogs in .dll format also provides for inheritance on a per-message basis. For example, in Austrian (de_AT) locale, translations from the German (de) message catalog will be used for messages not found in the Austrian message catalog. This has the consequence that the Austrian translators need only translate those few messages for which the translation into Austrian differs from the German one. Whereas when working with .resources files, each message catalog must provide the translations of all messages by itself.
  5. The GettextResourceManager that loads the message catalogs in .dll format also provides for a fallback: The English msgid is returned when no translation can be found. Whereas when working with .resources files, a language-neutral .resources file must explicitly be provided as a fallback.

On the side of the programmatic APIs, the programmer can use either the standard ResourceManager API and the GNU GettextResourceManager API. The latter is an extension of the former, because GettextResourceManager is a subclass of ResourceManager.

  1. The System.Resources.ResourceManager API.

    This API works with resources in .resources format.

    The creation of the ResourceManager is done through

      new ResourceManager(domainname, Assembly.GetExecutingAssembly())
    

    The GetString function returns a string’s translation. Note that this function returns null when a translation is missing (i.e. not even found in the fallback resource file).

  2. The GNU.Gettext.GettextResourceManager API.

    This API works with resources in .dll format.

    Reference documentation is in the csharpdoc directory.

    The creation of the ResourceManager is done through

      new GettextResourceManager(domainname)
    

    The GetString function returns a string’s translation. Note that when a translation is missing, the msgid argument is returned unchanged.

    The GetPluralString function returns a string translation with plural handling, like the ngettext function in C.

    The GetParticularString function returns a string’s translation, specific to a particular context, like the pgettext function in C. Note that when a translation is missing, the msgid argument is returned unchanged.

    The GetParticularPluralString function returns a string translation, specific to a particular context, with plural handling, like the npgettext function in C.

    To use this API, one needs the GNU.Gettext.dll file which is part of the GNU gettext package and distributed under the LGPL.

You can also mix both approaches: use the GNU.Gettext.GettextResourceManager constructor, but otherwise use only the ResourceManager type and only the GetString method. This is appropriate when you want to profit from the tools for PO files, but don’t want to change an existing source code that uses ResourceManager and don’t (yet) need the GetPluralString method.

Two examples, using the second API, are available in the examples directory: hello-csharp, hello-csharp-forms.

Now, to make use of the API and define a shorthand for ‘GetString’, there are two idioms that you can choose from:

Which of the two idioms you choose, will depend on whether copying two lines of codes into every class is more acceptable in your project than a class with a single-letter name.


Next: , Previous: Java, Up: List of Programming Languages   [Contents][Index]