vb.net - Unexpected Decimal Separator Behavior with CultureInfo in .NET - Stack Overflow

admin2025-04-15  0

In the attached images, you can observe that I am explicitly using both InvariantCulture and a new instance of CultureInfo("en-US") when converting a Double to a String:

value.ToString(Globalization.CultureInfo.InvariantCulture)
value.ToString(New Globalization.CultureInfo("en-US"))

Given these calls, the expected result should be the string "-807.7935669463161", where the decimal separator is a period (.). However, the output uses the comma (","), which matches the decimal separator of my system's regional settings.

I know how to implement a workaround, but why is the expected behavior not being respected?

If s <> value.ToString(us) Then
    Console.WriteLine($"Original value: {value}")
    Dim sFormatted As String =
        value.ToString(Globalization.CultureInfo.InvariantCulture)
    ' Should display "-807.7935669463161" :
    Console.WriteLine("sFormatted: " + sFormatted)
    ' Should display "-807.7935669463161" :
    Console.WriteLine("en-US Culture" +
             value.ToString(New Globalization.CultureInfo("en-US")))
    _usedVariables(s).Add(sFormatted)
End If

You may download the whole solution at here

****** EDIT ********* I have found what was happening. If you look at the following you will see that the last argument is a double, while the signature expects a String. But there is no error message and the code compiles and runs. So, this is because there is no Option Strict On declaration.

Dim us As New System.Globalization.CultureInfo("en-US")
Dim _usedVariables As New Dictionary(Of String, List(Of String))

Sub Main(args As String())
    Dim value As Double = 30
    Dim termValue As Double = 1.25
    Dim exponent As Double = value
    value = Math.Pow(termValue, value)
    AddToUsedVars(termValue.ToString(us) + "^" + exponent.ToString(us), -value)
End Sub

Public Sub AddToUsedVars(s As String, value As String)
    If Regex.IsMatch(s, "^\([^()]+\)") Then
        s = s.Substring(1, s.Length - 2)
    End If
    If Not _usedVariables.ContainsKey(s) Then
        _usedVariables.Add(s, New List(Of String))
    End If
    If s <> value.ToString(us) Then
        Console.WriteLine($"Original value: {value}")
        Dim sFormatted As String =
            value.ToString(Globalization.CultureInfo.InvariantCulture)
        ' Should display "-807.7935669463161" :
        Console.WriteLine("sFormatted: " + sFormatted)
        ' Should display "-807.7935669463161" :
        Console.WriteLine("en-US Culture" +
                 value.ToString(New Globalization.CultureInfo("en-US")))
        _usedVariables(s).Add(sFormatted)
    End If
End Sub

In the attached images, you can observe that I am explicitly using both InvariantCulture and a new instance of CultureInfo("en-US") when converting a Double to a String:

value.ToString(Globalization.CultureInfo.InvariantCulture)
value.ToString(New Globalization.CultureInfo("en-US"))

Given these calls, the expected result should be the string "-807.7935669463161", where the decimal separator is a period (.). However, the output uses the comma (","), which matches the decimal separator of my system's regional settings.

I know how to implement a workaround, but why is the expected behavior not being respected?

If s <> value.ToString(us) Then
    Console.WriteLine($"Original value: {value}")
    Dim sFormatted As String =
        value.ToString(Globalization.CultureInfo.InvariantCulture)
    ' Should display "-807.7935669463161" :
    Console.WriteLine("sFormatted: " + sFormatted)
    ' Should display "-807.7935669463161" :
    Console.WriteLine("en-US Culture" +
             value.ToString(New Globalization.CultureInfo("en-US")))
    _usedVariables(s).Add(sFormatted)
End If

You may download the whole solution at here

****** EDIT ********* I have found what was happening. If you look at the following you will see that the last argument is a double, while the signature expects a String. But there is no error message and the code compiles and runs. So, this is because there is no Option Strict On declaration.

Dim us As New System.Globalization.CultureInfo("en-US")
Dim _usedVariables As New Dictionary(Of String, List(Of String))

Sub Main(args As String())
    Dim value As Double = 30
    Dim termValue As Double = 1.25
    Dim exponent As Double = value
    value = Math.Pow(termValue, value)
    AddToUsedVars(termValue.ToString(us) + "^" + exponent.ToString(us), -value)
End Sub

Public Sub AddToUsedVars(s As String, value As String)
    If Regex.IsMatch(s, "^\([^()]+\)") Then
        s = s.Substring(1, s.Length - 2)
    End If
    If Not _usedVariables.ContainsKey(s) Then
        _usedVariables.Add(s, New List(Of String))
    End If
    If s <> value.ToString(us) Then
        Console.WriteLine($"Original value: {value}")
        Dim sFormatted As String =
            value.ToString(Globalization.CultureInfo.InvariantCulture)
        ' Should display "-807.7935669463161" :
        Console.WriteLine("sFormatted: " + sFormatted)
        ' Should display "-807.7935669463161" :
        Console.WriteLine("en-US Culture" +
                 value.ToString(New Globalization.CultureInfo("en-US")))
        _usedVariables(s).Add(sFormatted)
    End If
End Sub
Share Improve this question edited Feb 4 at 17:10 Olivier Jacot-Descombes 113k14 gold badges147 silver badges198 bronze badges asked Feb 4 at 14:24 Xavier JunquéXavier Junqué 4844 silver badges8 bronze badges 12
  • 1 meta.stackoverflow.com/questions/285551/… Please Include Code as Text not images – Richard Commented Feb 4 at 14:28
  • @Richard, I am sorry and I have edited and included the code. – Xavier Junqué Commented Feb 4 at 14:32
  • Please include a minimal reproducible example (stackoverflow.com/help/minimal-reproducible-example): this will at least show what type value is. – Richard Commented Feb 4 at 14:33
  • @Richard. Now, you may download the whole solution. The problem is arising in Module Term, at lines 192-198. – Xavier Junqué Commented Feb 4 at 14:52
  • 2 @XavierJunqué Now you know why Option Strict On is a really good idea ;) Also, the string concatenation operator in VB.NET is &, not +. – Andrew Morton Commented Feb 4 at 16:01
 |  Show 7 more comments

1 Answer 1

Reset to default 2

In the Sub AddToUsedVars you have a parameter value As String. Then you try to format it with value.ToString(<some culture info>). But this does not work, because value is already a String. It is not a Double. Change the parameter to value As Double, then your formats will work.

During formatting, the string is not perceived as a number and therefore no numeric formats are applied to it.


This happened because Option Strict was Off. in Visual Studio you can set the defaults for new VB projects and solutions in the menu Tools > Options:


For a specific project, you can set this option in the project properties, so that it applies to all project files where this option was not set explicitly:

转载请注明原文地址:http://www.anycun.com/QandA/1744713441a86588.html