Extension methods for translation engine 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 static implicit operator int(TranslateId id)
    {
        return id.Value;
    }
}


Any thoughts?
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.