When should I specify CurrentCulture or InvariantCulture and when should I leave it unspecified?
Asked Answered
L

2

22

What is the best practice for specifying CurrentCulture or InvariantCulture and not specifying the culture at all?

From what I have read, if you're doing serialization, for instance, you need InvariantCulture as a means of specifying a canonical representation of a data value. That's a relatively small percentage of culture-based string manipulations.

I find it long, verbose, and ugly most of the time to specify it every time I do, say:

var greeting = string.Format(CultureInfo.CurrentCulture, "Hello ", userName); 

However, my team recently turned FxCop on and now there's a push to always use CultureInfo EVERYWHERE. What is the best technique to combine brevity, readability, and functionality?

Some good reading material:

Lickspittle answered 12/7, 2010 at 19:3 Comment(0)
G
19

There is an inherent trade-off in play here.

At a minimum, you'll want to specify CultureInfo to use InvariantCulture whenever you are doing anything internal within your program. For example, using this with Serialization forces the data representation to always be the same, so you don't have to worry about internationalization issues with your internal data formats.

That being said, specifying this everywhere has some advantages - mainly in terms of forcing you to make sure you're handling this correctly. Internal program work vs. UI work needs to have a different culture specified (provided you want to properly localize your application). As a result, a complex program tends to require this to be specified everywhere, as leaving the "default" is dangerous at best, and tends to introduce bugs over time.

However, specifying this, as you noticed, tends to increase the size of your code, and potentially reduce the readability. This leads to the trade-off - readability and maintainability via shorter code vs. proper internationalization and localization and maintainability via being more explicit everywhere.

In my opinion, there is no "right" answer here - it really depends on your application. If your application is completely about presentation, and not doing a lot of data manipulation, especially not with any type of self-managed file storage, setting the current culture (and ui culture) once may be fine. I've found that more complicated applications tend to not work as well in this fashion, however, in which case the FxCop suggestions of specifying this everywhere seem more attractive.

Glassworker answered 12/7, 2010 at 19:16 Comment(8)
@Reed Copsey: I have also found that adding it everywhere as an FxCop reflex creates bugs -- several times I've seen instances where the wrong culture option was specified. This is obviously just an education problem, but is a common occurrence when something like FxCop tells you to do things but you don't necessarily understand why.Lickspittle
@Scott: True. But this is the case with everything in programming - if you are going to use it you need to understand it or it'll bite you. The only sane way to do localisation is to consider it when you first write the code - localising a completed product is one of the worst jobs to do, and an order of magnitude more expensive than thinking about it from the beginning.Malvinamalvino
I don't agree. Would I put the culture in all ToString() of my classes? I think logic and objects should be unaware of culture.Chazan
BTW, one way to get around the FXCop warnings and keep the code readable is to write wrapper methods of your own that hide the CultureInfo. i.e. write a FormatStringForUI() that will always use the UI culture. This cleans up your code and also gives programmers a simpler range of clearer choices: (e.g. UI or Serialisation?) (@onof: exactly :-)Malvinamalvino
@onof: I typically have a service to provide the culture, and specify it there. However, tt's really a matter of scale here - very large scale, internationally targetted projects need to take a lot of care to get culture "right" - and putting it everywhere tends to help.Glassworker
Got it. Indeed i did not consider to inject a localization service in business logic. ThanksChazan
An additional tip to go along with @Jason Williams suggestion of a "wrapper" method; you can just use an extension method. Consider something like: public static string ToInvariantString(this string s) { return s.ToString(CultureInfo.InvariantCulture); } then in your code, for any object you should be able to do myVariable.ToInvariantString(); without ReSharper or FxCop warnings. The only issue is that you would have to make the extension method for each type that specifies a ToString that takes a Culture, since that doesn't derive from Object.ToString()Dutiful
I can't seem to edit my own comment any more, but... Instead of making an extension method for string, int, long, etc... most .NET types seem to derive their ToString(IFormatProvider) method from IConvertible, so your extension method could just be: public static string ToInvariantString(this IConvertible convertible) Hope that helps someone down the road...Dutiful
D
5

The default is already the current culture as initialized by Windows. So using CultureInfo.CurrentCulture explicitly is just a waste of time. Any decent serialization format (including binary serialization and XML serialization) will serialize a DateTime in a culture invariant way.

Using a culture that is not the default is very dangerous. A thread will always be started with the default culture as specified by Windows and configured by the user when she installed Windows. .NET starts threadpool threads all the time and you'll risk getting a culture in that thread that is different from your main thread. Which can cause all manner of subtle problems. Like having a SortedList that suddenly isn't sorted anymore.

Daradarach answered 12/7, 2010 at 19:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.