There is a task in the extension of the base type string. The bottom line is that the string takes a different value depending on the user's country, so I need to do so, the string must store the ID of the localized string, when trying to take the value of the string, the localized string is returned. The problem is that you need to integrate it into an already completed environment without changing it.

  • And what did you do yourself? - DreamChild
  • In what sense? - Roman Sakutin
  • In direct. What have you done to solve this problem? You do not offer to solve it for you entirely? - DreamChild
  • No, not in any way. So far I have been able to find extension methods that are partially suitable for my task. But the fact is, I don’t know if it is possible to overload the operation of taking a value from a variable using them. - Roman Sakutin
  • ok, let's get more detailed then. Do you have a real task, or a training task? And what do you mean by overloading a value operation? - DreamChild

2 answers 2

You solve the localization problem. I have to say right away that adding localization without changing the surrounding code is a utopian task, and if it is put to you in this form, it has no solution. So explain to the designers of the problem. So it is necessary to redo the code, and the fact that the architect did not put this into the design is his personal file.

Now, about how to properly do the localization. I will tell in brief on the example of WPF, for WinForms it is done in the same way.

So, you have to find all the lines that the program displays, and put them in a ResourceDictionary . These same lines, but in other languages, must be compiled into separate DLLs (piece by language) with the name <Appname>.resources.dll ( <Appname> replace with the file name of your module), and placed in the appropriate subdirectories: English into a subdirectory en-US , Russian in ru-RU , Chinese in zh-CN , etc. These DLLs will be automatically loaded with a WPF framework and will replace the strings from the ResourceDictionary , which was mentioned at the beginning of this paragraph.

In your UI, any code like <Label>Enter password:</Label> should be replaced by <Label Content="{DynamicResource ID_ENTERPASSWORD}"/> (or more semantic: <Label Content="{DynamicResource 'UI.Authentication.PasswordRequest'}"/> , if you wish.) A more complex code that" adds "a string of pieces should not take pieces as a constant, but through App.FindResources("resource id here") . (Note that the lines will be static; you will need additional tricks to change the language on the fly.)

A great tutorial with examples is on MSDN.

Frequent problems:

  • Texts in different languages ​​have different lengths and occupy a different amount of space. Be prepared for the fact that your layout, "sharpened" under the English language, is torn apart. Be prepared for the fact that some single-line texts in German or Finnish will take two or three lines. Chinese characters are usually on average higher than Latin and Cyrillic.
  • A special thrill - support for RTL-languages : Hebrew and Arabic.
  • The same line in English may, depending on the context, have different translations into Russian. For example: “new” is sometimes translated as “new,” and sometimes as “create a document.” Put all possible contexts in different IDs, do not skimp on comments for translators.
  • In different languages ​​there are such troubles as declensions and conjugations, childbirth, cases and numbers. And a different word order in the sentence. Compare:
    • English: 1 file, 2 files, 5 files, 12 files
    • Russian: 1 file, 2 file, 5 files, 12 files
    • English: 5 seconds remains
    • Russian: 5 seconds left
    • English: 5 files and 2 directories copied
    • Russian: 5 files and 2 directory a are copied
  • Different languages ​​have different ideas about the formatting of numbers, dates, monetary amounts, etc. For example, the dot is used in English as a decimal separator, Germans and French use a comma, Italians can use an apostrophe. Date 2/3/4 in the United States means February 3, 2004, etc.
  • The task set for himself. Strings are stored as in android using XML. Yes, Fel is of course that in Unity3D there are no such tools out of the box and you have to write crutches to implement such basic features. In any case, thanks for the reply. - Roman Sakutin
  • @HolyMonkey: there is no particular difference: in Android, the strings are in XML, in WPF in ResourceDictionary (XAML). (I don’t know about Unity.) - VladD
  • In Unity3D in general, nothing is provided. Only in Android you do not need to create a DLL and everything is limited to folders with postfixes :) it is very convenient in terms of adding new lines. - Roman Sakutin
  • one
    @HolyMonkey: you can automate the creation of a DLL (that is, you need it), this is not a big question. In any case, localization is a rather big problem. Good luck with her decision! - VladD

If I understand you correctly, you can try to use the extension methods you mentioned. However, in their case, it must be remembered that they are nothing more than sittaxic sugar, which does not change the class itself, to which this method applies. For example:

 // Набор доступных языков public enum Language { Russiam, English, French } // Вспомогательный класс, реализующий логику перевода public static class Translator { public static string Translate(string str, Language lang) { // что-то там } } // класс для реализациии метода расширения public static class Extension { собственно сам метод расширения public static string WithLocale(this string str, Language locale) { return Translator.Translate(str, locale); } } 

Use this:

 string SomeStr = "check_button_text"; print(SomeStr.WithLocale(Language.Russian)); // вывод русскоязычного варианта print(SomeStr.WithLocale(Language.English)); // вывод англоязычного варианта 

The disadvantage of this approach is that you have to call the WithLocale method, but this, I think, is not a very large fee.

Alternatively, you can still create a class that extends the functionality of the standard String. However, System.String is a private class, so inheritance from it is impossible. Therefore, it will be necessary to make a new class that includes a certain string field and is able to format the string depending on the entered language. For it, you need an implicit operator to implicitly cast to and from the string.

  • I just found a partially suitable solution for myself. A class, with an overloaded implicit type casting operator, and with a localization change event for custom code to replace the text itself when it is necessary in the youth classes. The problem here is not that the code is overloaded with additional method calls, but that such a line should feel great wherever it is used because the implementation of libraries for which I write code cannot be changed. - Roman Sakutin