C# 从十进制转换时,字符串包含尾随零

C# 从十进制转换时,字符串包含尾随零,c#,asp.net,vb.net,winforms,C#,Asp.net,Vb.net,Winforms,我在写的一个程序中遇到了一个不寻常的怪癖,我试图找出是否有人知道原因。请注意,解决问题相当容易。我只是不明白为什么会发生这种事 我有一个用VB.NET编写的WinForms程序,它显示数据的子集。它包含几个显示数值的标签(标签的.Text属性直接从十进制值赋值)。这些数字由我用C#编写的DLL返回。DLL调用一个webservice,该webservice最初返回有问题的值。它返回一个字符串,另一个十进制(我对Web服务没有任何控制权,我只是使用它)。DLL将这些属性分配给对象上的属性(两者都是

我在写的一个程序中遇到了一个不寻常的怪癖,我试图找出是否有人知道原因。请注意,解决问题相当容易。我只是不明白为什么会发生这种事

我有一个用VB.NET编写的WinForms程序,它显示数据的子集。它包含几个显示数值的标签(标签的
.Text
属性直接从十进制值赋值)。这些数字由我用C#编写的DLL返回。DLL调用一个webservice,该webservice最初返回有问题的值。它返回一个字符串,另一个十进制(我对Web服务没有任何控制权,我只是使用它)。DLL将这些属性分配给对象上的属性(两者都是小数),然后将该对象返回给调用DLL的WinForm程序。显然,有很多其他数据正在从Web服务中消耗,但是没有其他操作可以修改这些属性

因此,简短的版本是:

  • WinForm从DLL请求一个新的
    Foo
  • DLL创建对象
    Foo
  • DLL调用webservice,它返回
    SomeOtherFoo

    //Both Foo.Bar1 and Foo.Bar2 are decimals
    Foo.Bar1 = decimal.Parse(SomeOtherFoo.Bar1); //SomeOtherFoo.Bar1 is a string equal to "2.9000"
    Foo.Bar2 = SomeOtherFoo.Bar2; //SomeOtherFoo.Bar2 is a decimal equal to 2.9D
    
  • DLL将Foo返回到WinForm

    WinForm.lblMockLabelName1.Text = Foo.Bar1 //Inspecting Foo.Bar1 indicates my value is 2.9D
    WinForm.lblMockLabelName2.Text = Foo.Bar2 //Inspecting Foo.Bar2 also indicates I'm 2.9D
    
那么,有什么怪癖

WinForm.lblMockLabelName1.Text显示为“2.9000”,而WinForm.lblMockLabelname2.Text显示为“2.9”

现在,我所知道的关于C#和VB的一切都表明,最初解析为十进制的字符串的格式应该不会影响后来对同一个十进制调用的decimal.ToString()操作的结果。我希望
decimal.Parse(someDecimalString).ToString()
将返回没有任何尾随零的字符串。我在网上找到的所有东西似乎都证实了这一点(有无数的堆栈溢出问题,问题恰恰相反……如何从最初的解析中保留格式)


目前,我刚刚从解析的初始字符串中删除了尾随的零,这隐藏了这个怪癖。然而,我想知道为什么会发生这种情况。

这是因为比例因子也是十进制数。尾随零不会影响算术或比较运算中十进制数的值。但是,如果应用了适当的格式字符串,ToString方法可能会显示尾随的零。

我会将
SomeOtherFoo.Bar2
的声明修改为设置为2.9000D,以使它们真正“等效”。我的想法是,
Parse
保留了十进制精度,即使正确的3位数字是0。不知道这是否能解决您的怪癖,但我不久前遇到了一些双精度和十进制解析问题,
decimal.Parse(stringNumber,CultureInfo.InvariantCulture)
测量这两个小数的工作真的一样吗?Foo.Bar1==Foo.Bar2吗?@JoelEtherton我无法控制其他人Foo。它由我正在使用的Web服务返回给我。不过,正如前面提到的,我并不特别关心“修复”它——我已经这样做了。问题是,如果有人知道它为什么会发生,而一切似乎都表明十进制不应该保留它最初是如何格式化的知识。您提到了精度…但不是所有的小数都具有相同的精度吗?我刚刚像这样快速地测试了您的代码,它产生了
2.9000
var somemString=decimal.Parse(“2.9000”).ToString();你有没有在标签上设置一些最大长度,或是什么样的长度作为参考。我发誓后面的零会被消除,但事实似乎并非如此。这让我想知道我在StackOverflow上发现的所有问题,这些问题都是关于如何在转换后保留尾随零。。。