mono or dotnet8.0
mono-mcs or dotnet8
cs
"abc", @"abc"
_("abc")
GettextResourceManager.GetString,
GettextResourceManager.GetPluralString
GettextResourceManager.GetParticularString
GettextResourceManager.GetParticularPluralString
new GettextResourceManager(domain)
—, compiled message catalogs are located in subdirectories of the directory containing the executable
automatic
—
—, uses a C# specific message catalog format
xgettext -k_
String.Format "{1} {0}"
fully portable
—
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.
.resources format is a binary file usually generated through the
resgen or monoresgen 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.
.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 monoresgen program (from the mono/mcs package).
This program 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.
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:
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.
.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.
.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.
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.
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.
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).
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:
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."));
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.