C#: atestat și pregătire ONTI

C#: resurse localizate și texte fără concatenări fragile

Organizează textele unei aplicații C# pentru schimbarea limbii. Folosește chei, formatare și o regulă de fallback înainte de integrarea cu fișiere resx.

Textele scrise direct în zeci de handleri sunt greu de corectat sau tradus. Separăm cheia mesajului de valoarea afișată. Începem cu un dicționar mic pentru a înțelege mecanismul, apoi îl poți muta în resurse .resx gestionate de Visual Studio. Schimbarea limbii nu trebuie să schimbe ID-urile sau regulile aplicației.

Cum lucrezi cu exemplul

Programul complet folosește C# 7.3 și API-uri disponibile în .NET Framework 4.8. Deschide Lesson.csproj din arhivă sau creează un proiect Console App (.NET Framework 4.8) și înlocuiește Program.cs. Datele de demonstrație sunt incluse în cod.

Descarcă sursele și instrucțiunile.

Ideea și pașii de implementare

Fiecare limbă are aceleași chei: title, save și count. Mesajul count conține un parametru {0}, completat prin string.Format. Alegerea limbii este o valoare separată. Funcția TextFor caută în limba activă și revine la română dacă lipsește cheia; lipsa și în română este o eroare explicită.

Într-un proiect cu resx, ResourceManager și CurrentUICulture oferă mecanisme pentru selecția resurselor. CurrentCulture influențează formatarea numerelor și datelor, în timp ce CurrentUICulture este folosită pentru alegerea textelor interfeței. Nu le considera identice ca responsabilitate.

Exemplu și rezultat așteptat

În română, cheia save produce Salveaza, iar count cu valoarea 3 produce Carti: 3. În engleză obții Save și Books: 3. Același număr și aceeași cheie de domeniu sunt folosite în ambele cazuri; doar prezentarea diferă.

Schemă pentru lecția 27: Cheie: count; Limba: ro / en; Parametru: 3; Carti: 3 / Books: 3.Cheie: count → Limba: ro / en → Parametru: 3 → Carti: 3 / Books: 3.Mărește schema ↗

Codul complet

using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Globalization;
using System.Xml.Linq;
using System.Data;
class Program {
    static readonly Dictionary<string,string> ro=new Dictionary<string,string> {
        {"save","Salveaza"},{"count","Carti: {0}"},{"title","Biblioteca"}};
    static readonly Dictionary<string,string> en=new Dictionary<string,string> {
        {"save","Save"},{"count","Books: {0}"},{"title","Library"}};
    static string TextFor(string language,string key) {
        string value; var selected=language=="en" ? en : ro;
        if(selected.TryGetValue(key,out value) || ro.TryGetValue(key,out value))return value;
        throw new KeyNotFoundException(key);
    }
    static void Main() {
        foreach(string language in new[] {"ro","en"}) {
            Console.WriteLine(TextFor(language,"save"));
            Console.WriteLine(string.Format(CultureInfo.InvariantCulture,TextFor(language,"count"),3));
        }
    }
}

Rezultatul programului:

Salveaza
Carti: 3
Save
Books: 3

Greșeli și limite

Nu construi propoziții prin concatenarea multor bucăți traduse independent: ordinea cuvintelor poate varia. Nu folosi textul butonului pentru a decide ce comandă execută. Nu presupune că textul tradus are aceeași lungime; verifică layout-ul cu valori mai lungi și cu diacritice.

Exersează

Adaugă cheia cancel în română, dar nu în engleză, și verifică fallback-ul. Adaugă apoi traducerea și confirmă schimbarea. Mută cheile într-un fișier Resources.resx și într-un Resources.en.resx într-un proiect de probă. Verifică ecranul la ambele limbi fără să schimbi datele salvate.

Continuă parcursul

Parcursul complet de 50 de lecții

Bazele C#

Lecția precedentă: C#: rapoarte tipărite și paginare cu PrintDocument

Lecția următoare: C#: Undo și Redo pentru modificări controlate.

Referință: documentația Microsoft.

Întrebări frecvente

Textul tradus poate fi folosit drept ID?

Nu. Folosește chei stabile și păstrează textul numai pentru prezentare.

CurrentCulture și CurrentUICulture sunt același lucru?

Au roluri diferite: formatarea valorilor, respectiv selectarea resurselor interfeței.

De ce am nevoie de fallback?

Pentru un comportament previzibil când o traducere lipsește, fără text gol ascuns.

Un pas mai departe

Autentifică-te pentru a păstra progresul în cont.

Exersează cu o problemă →