0

In a .Net 6 console app, I have set up a String resource Strings in a separate library project such that String.MyString = "string" in Strings.resx and "foreign string" in Strings.sv.resx... this was done by simply adding a new Resources File to the project and using the visual tool to add strings.

I want to set my application culture to locale "sv" throughout so I wrote this test code:

internal class Program
{
  private static async Task Main(string[] args)
  {
    var culture = CultureInfo.CreateSpecificCulture("sv");
    Console.WriteLine($"1: {Strings.MyString}");
    CultureInfo.DefaultThreadCurrentCulture = culture;
    Console.WriteLine($"2: {Strings.MyString}");
    Thread.CurrentThread.CurrentCulture = culture;
    Console.WriteLine($"3: {Strings.MyString}");
    Strings.Culture = culture;
    Console.WriteLine($"4: {Strings.MyString}");
    ...

Output:

1: string
2: string
3: string
4: foreign string

My expectation is that only the first line would be "string" since I change the culture. Forcibly changing the localization on Strings is the only way that works and seems a really bad way to do it.

Every example I have seen seems to favor the Thread approach (3) so what is not working? Isn't Strings supposed to use the thread/application locale?

Mr. Boy
  • 60,845
  • 93
  • 320
  • 589
  • How is `Strings` implemented? If it's using code generated in "Resources.Designer.cs" chances are that the `ResourceManager` object is a singleton and additionally [resource strings are cached](https://stackoverflow.com/questions/15928233/are-resourcestrings-really-cached) so the value isn't going to change once you've accessed it. – Matthew Watson Nov 16 '22 at 13:45
  • @MatthewWatson `project->add->resources file` IIRC I didn't touch the code-behind file. Interesting note on caching, my tests might affect each other... – Mr. Boy Nov 16 '22 at 14:08

1 Answers1

1

Not sure about exact difference between CurrentUICulture and CurrentCulture of Thread.CurrentThread but changing CurrentUICulture is enough for changes to be applied.

I have two files in project:

  1. Strings.resx - default culture strings are located here (English)

  2. Strings.ru.resx - Russian-translated strings are here

    Console.WriteLine($"Default culture: {Strings.TestString}");
    
    var ruCulture = new CultureInfo("ru");
    
    Thread.CurrentThread.CurrentUICulture = ruCulture;
    
    Console.WriteLine($"{ruCulture}: {Strings.TestString}");
    

Output:

Default culture: English
ru: Русский

As a side note, no matter what your default actual culture is - it will search resources in primary *.resx file (without culture suffix).
But when changing to alternative culture .resx with suffix will be searched (.ru.resx in my case).

PS: Rider has nice designer to edit several files from single form. Not sure about Visual Studio.

Ryan
  • 609
  • 6
  • 13
  • 1
    That sounds promising, I found this FYI if you want to reference: https://stackoverflow.com/questions/329033/what-is-the-difference-between-currentculture-and-currentuiculture-properties-of – Mr. Boy Nov 16 '22 at 14:14
  • This works, in fact `CultureInfo.DefaultThreadCurrentUICulture` does too which I think is even nicer (I believe this was added in more recent .Net) – Mr. Boy Nov 16 '22 at 14:19
  • Yeah, i saw that, but it's kinda obsolete, no ArgumentException is thrown for CurrentCulture for let's say `ru`. Need to dig further from scratch. – Ryan Nov 16 '22 at 14:23