DEV Community

Cover image for C# Tip: How to temporarily change the CurrentCulture
Davide Bellone
Davide Bellone

Posted on • Originally published at code4it.dev

C# Tip: How to temporarily change the CurrentCulture

It may happen, even just for testing some functionalities, that you want to change the Culture of the thread your application is running on.

The current Culture is defined in this global property: Thread.CurrentThread.CurrentCulture. How can we temporarily change it?

An idea is to create a class that implements the IDisposable interface to create a section, delimited by a using block, with the new Culture:

public class TemporaryThreadCulture : IDisposable
{
    CultureInfo _oldCulture;

    public TemporaryThreadCulture(CultureInfo newCulture)
    {
        _oldCulture = CultureInfo.CurrentCulture;
        Thread.CurrentThread.CurrentCulture = newCulture;
    }

    public void Dispose()
    {
        Thread.CurrentThread.CurrentCulture = _oldCulture;
    }
}
Enter fullscreen mode Exit fullscreen mode

In the constructor, we store the current Culture in a private field. Then, when we call the Dispose method (which is implicitly called when closing the using block), we use that value to restore the original Culture.

How to use it

How can we try it? An example is by checking the currency symbol.

Thread.CurrentThread.CurrentCulture = new CultureInfo("ja-jp");

Console.WriteLine(Thread.CurrentThread.CurrentCulture.NumberFormat.CurrencySymbol); //¥

using (new TemporaryThreadCulture(new CultureInfo("it-it")))
{
    Console.WriteLine(Thread.CurrentThread.CurrentCulture.NumberFormat.CurrencySymbol);//€
}

Console.WriteLine(Thread.CurrentThread.CurrentCulture.NumberFormat.CurrencySymbol); //¥
Enter fullscreen mode Exit fullscreen mode

We start by setting the Culture of the current thread to Japanese so that the Currency symbol is ¥. Then, we temporarily move to the Italian culture, and we print the Euro symbol. Finally, when we move outside the using block, we get back to ¥.

Here's a test that demonstrates the usage:

[Fact] 
void TestChangeOfCurrency()
{
    using (new TemporaryThreadCulture(new CultureInfo("it-it")))
    {
        var euro = CultureInfo.CurrentCulture.NumberFormat.CurrencySymbol;
        Assert.Equal(euro, "€");

        using (new TemporaryThreadCulture(new CultureInfo("en-us")))
        {
            var dollar = CultureInfo.CurrentCulture.NumberFormat.CurrencySymbol;

            Assert.NotEqual(euro, dollar);
        }
        Assert.Equal(euro, "€");
    }
}
Enter fullscreen mode Exit fullscreen mode

Conclusion

Using a class that implements IDisposable is a good way to create a temporary environment with different characteristics than the main environment.

I use this approach a lot when I want to experiment with different cultures to understand how the code behaves when I'm not using English (or, more generically, Western) culture.

Do you have any other approaches for reaching the same goal? If so, feel free to share them in the comments section!

Happy coding!

🐧

Discussion (1)

Collapse
polterguy profile image
Thomas Hansen

Najs one! :)

You can generalise the above pattern, by further providing two Action arguments, to the CTOR of a class called e.g. Executor, resulting in generalised deterministic execution of code, the same way you'd use destructors in C#. I once create an HTML renderer using such tricks :)

It becomes a bit tricky as you start having code that might throw exceptions, etc - But still a nice way to achieve "deterministic execution" ... :)