- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
背景:我最近有幸编写了需要在国际范围内可靠地将字符串转换为 double 的代码。此功能也必须分发。即字符串存储在数据库中,需要在跨不同区域设置的众多代理上转换为数字。出于限制原因,更改数据库模式是不可能的,我必须在遗留代码库中使用简单的升级路径并且不破坏现有功能来完成这项工作。
我能够通过将存储的字符串规范化为不变格式并在编码中添加一个标志来指示该值是否已规范化以及应该采用新路径还是非规范化(sp?)并采用旧路径来解决这个问题路径。
我忘了提到原始值是由最终用户输入的,并且必须在可接受的格式范围内。这意味着存储的值可能有也可能没有数字分组说明符。显然这是危险的,它目前仅适用于测试版,并且预计很快就会对 UI 进行适当的国际化以进行适当的发布。
也就是说,我认为我的转换代码应该能够处理数字分组字符是合理的,即使最终的规范化形式不包括它们。带有适当文化格式的 Double.TryParse() 和 Double.ToString() 应该可以毫无问题地处理这个问题,并且可以出于其他原因重用转换代码(是的遗留代码!)。
.NET 错误 所以我认为围绕国际化字符串编写一些单元测试是个好主意,以双重转换代码。
我写了两个主要测试(一种伪代码)。
测试 1:
Double testValue = 15000.05
foreach (CultureInfo ci in CultureInfo.GetCultures(CultureTypes.AllCultures)
{
string testString = testValue.ToString(ci);
Assert.AreEqual(testValue, Convert(testString, ci));
}
测试 2:
foreach (CultureInfo ci in CultureInfo.GetCultures(CultureTypes.AllCultures)
{
string testString = testValue.ToString("N2", ci);
Assert.AreEqual(testValue, Convert(testString, ci));
}
相关转换代码(几乎一行一行):
If Not Double.TryParse(numIn, Globalization.NumberStyles.Any, cultureInfo, numOut) Then Return False
为了测试,收集所有文化代码的确切方法可能不同,Convert 的方法签名不同,周围的代码和断言略有不同。相关部分是 .ToString(ci) 和 .ToString("N2", ci)。对于 en-US,这些版本将分别生成“15000.05”和“15,000.05”。此外,此代码在 .NET 版本 2.0 - 4.5.2 下运行,我们在各种相关版本下运行测试。它在所有方面的行为都相同(*可能需要仔细检查,但这绝对是 .NET 4.5.2 中的行为)
测试 1 通过!
测试 2 在这 5 个文化代码上失败:
我们目前正在忽略这些不受支持的故障,并跟踪是否出现我们关心的任何新故障。
诊断在四处挖掘和试验一些之后,我们将问题追溯到数字分组说明符。即千位分隔符。将 Double.TryParse() 更改为
numOut = Double.Parse(numIn, ci)
有效。所以这个问题特别与 Double.TryParse() 有关,并且可能与 NumberStyle.Any 说明符有关。 Or'ing 它与十六进制说明符也不起作用。
因此我们在 .NET 中遇到了这样一种情况,您可以使用特定的 IFormatProvider 将 double 型转换为字符串,然后尝试使用相同的 IFormatProvider 将其转换回 double 型,但会失败。
问题:谁能解释为什么会这样?
运行理论:我目前的两个想法是数字分组字符的字符编码错误,或者那些特定文化的实际 double 表示是不同的(类似于 double x = 0.3 是在 .NET 中真的是 0.299...)。
免责声明:我在 VB.NET 和 C# 之间切换,所以请原谅任何语法混淆。另外,我知道该测试没有正确说明“奇数”数字分组,例如在印地语中 1,015,000 写成 10,15,000。
最佳答案
@tarekgh 在 GitHub issue 上发布了一个答案.以下是他写的:
“这里的问题是失败的文化,因为你有以下几点:
小数点分隔符是“,”组分隔符是“.”货币小数点分隔符是“.”货币组分隔符为“,”请注意,小数分隔符与货币组分隔符相同。组分隔符与货币小数点分隔符相同。
现在当您用这种文化格式化数字时,您将得到字符串“15.000,05”。当您尝试解析它时,您传递的是 NumberStyles.Any,这意味着该字符串可以是货币数字,也可以是十进制数字。这会在尝试解析字符“.”时混淆解析器。因为它可以被视为货币小数点分隔符,也可以被视为组分隔符。解析器决定将其视为货币小数点分隔符。然后解析器将继续直到命中“,”并再次将其视为货币组分隔符。因为组分隔符不能出现在小数分隔符之后,解析器将无法解析字符串并从 TryParse 返回 false(或从 Parse 抛出异常)。
解决此问题的方法是从传递的 NumberStyles 中删除货币解析。即
Double.TryParse(numString, NumberStyles.Any & (~NumberStyles.AllowCurrencySymbol), ci, out numParsed);
我将关闭这个问题,但如果您有任何问题,请随时回复。”
关于c# - .NET Double.TryParse(num, format, cultureinfo, out) 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44559594/
创建使用.NET框架的asp.net页面时,访问该页面的客户端是否需要在其计算机上安装.NET框架? IE。用户访问www.fakesite.com/default.aspx,如果他们没有安装框架,他
我阅读了很多不同的博客和 StackOverflow 问题,试图找到我的问题的答案,但最后我找不到任何东西,所以我想自己问这个问题。 我正在构建一个应用程序,其中有一个长时间运行的工作线程,它执行一些
已锁定。这个问题及其答案是locked因为这个问题是题外话,但却具有历史意义。目前不接受新的答案或互动。 我一直想知道为什么微软为这样一个伟大的平台选择了一个如此奇怪的、对搜索引擎不友好的名称。他们就
.Net Framework .Net .NET Standard的区别 1、.NET Framework 在未来.NET Framework或许成为过去时,目前还是有很多地方在使用的。这一套
如果有选择的话,您会走哪条路? ASP.NET Webforms + ASP.NET AJAX 或 ASP.NET MVC + JavaScript Framework of your Choice
我有一个 Web 服务,它通过专用连接通过 https 使用第三方 Web 服务,我应用了 ServicePointManager.ServerCertificateValidationCallbac
为什么我应该选择ASP.NET Web Application (.NET Framework)而不是ASP.NET Core Web Application (.NET Framework)? 我在
我在网络上没有找到任何关于包含 .NET Standard、.NET Core 和 .NET Framework 项目的 .NET 解决方案的公认命名约定。 就我而言,我们在 .NET 框架项目中有以
.NET Compact 是 .NET 的完美子集吗? 假设我考虑了屏幕大小和其他限制并避免了 .NET Compact 不支持的类和方法,或者 .NET Compact 是一个不同且不兼容的 GUI
我已经阅读了所有我能找到的关于 connectionManagement 中的 maxconnection 设置的文章:即 http://support.microsoft.com/kb/821268
我现在正在使用asp.net mvc,想知道使用内置的Json或 Json.Net哪个是更好的选择,但我不确定一个人是否比另一个人有优势。 另外,如果我确实选择沿用Json.Net的路线,那么我应该选
在 Visual Studio 中,您至少可以创建三种不同类型的类库: 类库(.NET Framework) 类库(.NET 标准) 类库(.NET Core) 虽然第一个是我们多年来一直使用的,但我
.NET 和 ASP.NET 之间有什么区别?它们有什么关系? 最佳答案 ASP.Net 基于 .Net 框架构建,提供有关 Web 开发的附加功能。 你可以去看看wikipedia article
在安装更高版本(3.0)之前,我需要安装.net框架1.1和2.0吗?或者单独安装 3.0 框架就足够了,并为在早期框架版本上编写的软件提供支持?谢谢 ,丽然 最佳答案 不,您不必安装以前的框架。 我
我正在开发一个项目,人们可以“更新”类别,例如更改类别的名称。我收到以下消息 This is called after clicking update 按钮 with the SQL statemen
.NET 类 System.Net.CookieContainer 线程安全吗? --更新:交 key 答复-- 是否有任何方法可以确保异步请求期间修改的变量(即 HttpWebRequest.Coo
我正在使用 JScript.NET 在我编写的 C# WinForms 应用程序中编写脚本。它工作得很好,但我只是尝试在脚本中放置一些异常处理,但我无法弄清楚如何判断我的 C# 代码抛出了哪种类型的异
我需要你的帮助, 比如我有一个小数类型的变量,我想这样取整。 例如 3.0 = 3 3.1 = 4 3.2 = 4 3.3 = 4 3.4 = 4 3.5 = 4 3.6 = 4 3.7 = 4 3.
我使用过这样的代码:http://msdn.microsoft.com/en-us/library/dw70f090.aspx在 ASP.NET 中工作之前访问数据库(2-3 年前)。我没有意识到我正
自 ConfigurationManager .NET Standard 中不存在,检索正在执行的程序集的应用程序设置的最佳方法是什么,无论是 web.config或 appSettings.{env
我是一名优秀的程序员,十分优秀!