views:

166

answers:

5

I'm seeing an issue in a production ASP.NET application that involves the following code, which is used to render the geocoordinates of a particular object:

private double _longitude;
private double _latitude;

public string ToCsvString()
{
    return _latitude + "," + _longitude;
}

Thread.CurrentThread.CurrentCulture will be set to different values based on the incoming request. The behavior I'm seeing is that the result of this function will vary independent of the threadlocal culture. At times the decimal points and commas are incorrect for the current culture. More strangely, it seems that once set wrong, the wrong value persists.

Does ToString on double cache values?

+1  A: 

Why not use the explicit ToString methods which allow you to manually specify a culture-specific IFormatProvider?

Anon.
I think the above code would not compile at all and the OP has simply forgotten to add the `.ToString()`.
Vilx-
It compiles. String concatenation automatically invokes the ToString()
Thomas H
Yes, I have changed the code to use an explicit IFormatProvider as a workaround. I am simply curious about the behavior for future reference.
Thomas H
+2  A: 

It shouldn't cache the values, especially because of the culture issue you mentioned. Two things come to mind:

  1. How/where do you set the culture? Perhaps there is a bug there?
  2. Are you sure it is THIS place that creates the bug? Perhaps the culture is different than you think? Perhaps the results of this function are cached elsewhere in your code?
Vilx-
I can't completely rule out a bug elsewhere. In fact that was my initial instinct. I just wanted to rule a potential issue in the core library and couldn't find a quick answer.
Thomas H
This is a highly unlikely issue. And if it were such, then VERY many people would be affected, and there would be articles about it all over the place.
Vilx-
A: 

For rendering geocoordinates, I suggest that you best define your own fixed formatting or culture rather than leaving it for the framework, default culture setting or culture info of the running thread.

I would do it like this to format it to 4 decimal points:

return _latitude.ToString("0.0000") + "," + _longitude.ToString("0.0000");

or

string.Format("{0:0.0000}, "{1:0.0000}", _latitude, _longitude);

Or if you want the decimal separator to be culture specific,

CultureInfo ci = System.Globalization.CultureInfo.GetCultureInfo("en-AU");
return _latitude.ToString("N4", ci) + "," + _longitude.ToString("N4", ci);
Fadrian Sudaman
A: 

If you always want Double.ToString to return consistent values regardless of culture, use an InvariantCulture:

someDouble.ToString(CultureInfo.InvariantCulture); 
Paul Betts
A: 

Operations such as ToString on double or any other immutable object are by definition thread safe. Since you are guaranteed that the state of those object never change an operation will always yield the same result, that result might however be based on the environment it's executed in but it will always yield the same result in the same environment. Since there are no side effects on immutable types ToString cannot cache the result

Rune FS