从 .Net 2.0 升级到 .Net 4.5.2 后的字符串格式异常

本文关键字:Net 字符串 异常 格式 | 更新日期: 2023-09-27 18:32:46

我最近将 ASP.Net 表单应用程序升级到 .Net 4.5.2,在修复了一些相对琐碎的命名空间问题后,我能够成功构建解决方案。但是在运行时,我收到以下错误:

mscorlib 中发生了类型为"System.FormatException"的异常.dll但未在用户代码中处理

调试时由以下行抛出:

string.Format("Init took {0:mm:ss}", (object) DateTime.Now.Subtract(renderStartTime))  

其中 renderStartTime = DateTime.Now

我有点困惑为什么我在升级后看到此错误。有什么想法吗?

从 .Net 2.0 升级到 .Net 4.5.2 后的字符串格式异常

这是一个重大更改。

请参见: .NET Framework 4 中的格式化和分析时间间隔

.NET Framework 3.5 及更早版本中,TimeSpan 不会 实现IFormattable也不支持格式字符串。 因此,"r"格式字符串将被忽略,并且无参数 调用 TimeSpan.ToString 方法。在 .NET Framework 4 中,在 另一方面,TimeSpan.ToString(String, IFormatProvider( 被调用和 传递了不受支持的格式字符串,这会导致异常。

只是为了扩展答案,.Net Framework 2.0 中的原始代码不会引发异常,但它不会为您提供所需的输出(分钟:秒(。由于参数 less 构造函数将被调用 TimeSpan,忽略 String.Format 中指定的格式。但是,在.Net框架4.0或hgiher中,由于TimeSpan实现了IFormattable,指定的格式mm:ss将被传递给ToString调用。现在这种格式mm:ssTimeSpan无效,它要求冒号用反斜杠转义,如:mm':ss。这就是为什么你会得到例外。

请参阅: 自定义时间跨度格式字符串

在 .Net 3.5 或更低版本中,可以使用:

TimeSpan elapsed = DateTime.Now - renderStartTime; //or DateTime.Now.Subtract(renderStartTime)
string formatted = string.Format("Init took {0}:{1}", elapsed.Minutes, elapsed.Seconds); //returns minutes and seconds components, 
                                        // If you are looking for Total Minutes and Total Seconds then use TotalMinutes/TotalSeconds

在 .Net Framework 4.0 或更高版本中,您可以执行以下操作:

string.Format("Init took {0:mm'':ss}", elapsed);

问题是第二个冒号。 您可以改为执行以下操作

string.Format("Init took {0:mm}:{0:ss}", DateTime.Now.Subtract(renderStartTime));

编辑

根据TimeSpan在.Net 3.5及更早版本中的工作方式,.Net 2.0中的原始代码实际上将以hh:mm:ss格式打印出时间。 基本上,格式的"mm:ss"部分被忽略了,因为TimeSpan没有实现IFormattable。 因此,.Net 4.5.2 中的以下内容实际上更接近于替换原始代码在 .Net 2.0 中执行的操作。

string.Format("Init took {0}", DateTime.Now.Subtract(renderStartTime));

但是,如果只想显示分钟和秒,则可以在 .Net 4.0 及更高版本中使用 {0:mm}:{0:ss}{0:mm'':ss} 格式。 或者在 .Net 3.5 或更早版本中,您必须这样做。

TimeSpan diff = DateTime.Now.Subtract(renderStartTime);
string.Format("Init took {0:00}:{1:00}", diff.Minutes, diff.Seconds);
 Console.WriteLine(string.Format("Init took {0:mm'':ss}", DateTime.Now.Subtract(renderStartTime)));

在这里,您需要代码如下所示。如果你愿意,你可以这样做

 Console.WriteLine(string.Format(@"Init took {0:mm':ss}", DateTime.Now.Subtract(renderStartTime)));

您可以阅读此微软文档以获取更多帮助:

自定义 TimeSpan 格式说明符不包括占位符 分隔符符号,例如将天与小时分开的符号, 小时从分钟开始,或秒到秒的小数部分。相反,这些 符号必须作为字符串包含在自定义格式字符串中 文字。例如,"dd.hh:mm"将句点 (.( 定义为 天和小时之间的分隔符以及冒号 (:)作为分隔符 在小时和分钟之间。自定义时间跨度格式说明符也可以 不包括使您能够区分 负和正时间间隔。要包含符号符号,您需要 必须使用条件逻辑构造格式字符串。这 "其他字符"部分包含一个示例。