patterncsharpMinor
Extension methods for translation engine
Viewed 0 times
engineextensionmethodsfortranslation
Problem
Our application uses some singletons for localized strings. These calls used to be long and dirty. Therefore some co-worker created extensions for the
What does the code do: Find a translation string based on the key (the
However, I think this approach is bad because:
Trying to provide him with a better approach, all I could think of was a struct using implicit operators as below. However, I think this casting is bad practise as well..
To make this question complete, here is my code for the struct type.
```
public struct TranslateId
{
private readonly int m_Value;
public TranslateId (int value)
{
m_Value = value;
}
public int Value
{
get { return m_Value; }
}
public string Translate(string defaultString, params object[] parameters)
{
// TODO: Use the actual singleton to retrieve translation
string translationResult = defaultString;
// Return the formatted retrieved value
return string.Format(translationResult, parameters);
}
public static implicit operator TranslateId(int value)
{
return new TranslateId(value);
}
public st
int and string type to ease the usage of translations.What does the code do: Find a translation string based on the key (the
int value). If it cannot be found it falls back to the first provided string. The latter is a params[] string used in underlying string.Format() method as parameters.const var warrantyDescription = "14";
var text = 4426.Translate("Garantietermijn {0} mnd", warrantyDescription);However, I think this approach is bad because:
- Bad SoC.
Intandstringhave nothing todo with translations
- This will result in unreadable and unmaintainable code from the perspective of other developers, encountering a extended int with specific functionality. Imagine a case where not only translations but xx other functionalities extend the int as it is a unique identifier.
Trying to provide him with a better approach, all I could think of was a struct using implicit operators as below. However, I think this casting is bad practise as well..
const string warrantyDescription = "14";
var text = ((TranslateId) 4426).Translate( "Garantietermijn {0} mnd", warrantyDescription );To make this question complete, here is my code for the struct type.
```
public struct TranslateId
{
private readonly int m_Value;
public TranslateId (int value)
{
m_Value = value;
}
public int Value
{
get { return m_Value; }
}
public string Translate(string defaultString, params object[] parameters)
{
// TODO: Use the actual singleton to retrieve translation
string translationResult = defaultString;
// Return the formatted retrieved value
return string.Format(translationResult, parameters);
}
public static implicit operator TranslateId(int value)
{
return new TranslateId(value);
}
public st
Solution
This is a horrible misuse of extension methods. The only thing worse (and I'm sure you'll see it) is
(n+5).Translate(...). You're absolutely correct - the starting point for the mistake is in thinking of the integer as the base object for the translation. There are a number of well-understood patterns for handling localization, and this isn't any of them. Since we're talking C#, there's the obvious resource technique, but there are others as well. The GNU Project pioneered the _("blah blah blah") mechanism, where the default string serves as a key in a locale-specific table of replacements (along with the Windows OS and MS Office, this is one of the most prevalent and successful translation systems). And then there's the tried-and-true dictionary-indexed-by-a-named-constant (often an enum member), often encapsulated behind a Language class with a Translate(...) method.Context
StackExchange Code Review Q#10659, answer score: 5
Revisions (0)
No revisions yet.