HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Extension methods for translation engine

Submitted by: @import:stackexchange-codereview··
0
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 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. Int and string have 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.