[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [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 ResourceSet
s that can be directly loaded by
the C# runtime: .resources
files and .dll
files.
-
The
.resources
format is a binary file usually generated through theresgen
ormonoresgen
utility, but which doesn’t support plural forms..resources
files can also be embedded in .NET.exe
files. This only affects whether a file system access is performed to load the message catalog; it doesn’t affect the contents of the message catalog. -
On the other hand, the
.dll
format is a binary file that is compiled from.cs
source code and can support plural forms (provided it is accessed through the GNU gettext API, see below).
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:
-
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. -
Plural handling: A message catalog in
.dll
format supports the plural handling functionGetPluralString
. Whereas.resources
files can only contain data and only support lookups that depend on a single string. -
Context handling: A message catalog in
.dll
format supports the query-with-context functionsGetParticularString
andGetParticularPluralString
. Whereas.resources
files can only contain data and only support lookups that depend on a single string. -
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. -
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
.
-
The
System.Resources.ResourceManager
API.This API works with resources in
.resources
format.The creation of the
ResourceManager
is done throughnew 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). -
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 throughnew 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 thengettext
function in C.The
GetParticularString
function returns a string’s translation, specific to a particular context, like thepgettext
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 thenpgettext
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:
-
In a unique class of your project, say ‘Util’, define a static variable
holding the
ResourceManager
instance:public static GettextResourceManager MyResourceManager = new GettextResourceManager("domain-name");
All classes containing internationalized strings then contain
private static GettextResourceManager Res = Util.MyResourceManager; private static String _(String s) { return Res.GetString(s); }
and the shorthand is used like this:
Console.WriteLine(_("Operation completed."));
-
You add a class with a very short name, say ‘S’, containing just the
definition of the resource manager and of the shorthand:
public class S { public static GettextResourceManager MyResourceManager = new GettextResourceManager("domain-name"); public static String _(String s) { return MyResourceManager.GetString(s); } }
and the shorthand is used like this:
Console.WriteLine(S._("Operation completed."));
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.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This document was generated on June 7, 2014 using texi2html 5.0.