string.Format返回的字符串似乎使用了一些奇怪的编码.与源代码中声明的字符串中包含的空格相比,格式字符串中包含的空格使用不同的字节值表示.
以下测试用例演示了该问题:
[Test]
public void FormatSize_Regression()
{
string size1023 = FileHelper.FormatSize(1023);
Assert.AreEqual("1 023 Bytes", size1023);
}
Run Code Online (Sandbox Code Playgroud)
失败:
String lengths are both 11. Strings differ at index 1.
Expected: "1 023 Bytes"
But was: "1 023 Bytes"
------------^
FormatSize方法:
public static string FormatSize(long size)
{
if (size < 1024)
return string.Format("{0:N0} Bytes", size);
else if (size < 1024 * 1024)
return string.Format("{0:N2} KB", (double)((double)size / 1024));
else
return string.Format("{0:N2} MB", (double)((double)size / (1024 * 1024)));
}
Run Code Online (Sandbox Code Playgroud)
在Assert行上设置断点时从VS立即窗口:
size1023
"1 023 Bytes"
System.Text.Encoding.UTF8.GetBytes(size1023)
{byte[12]}
[0]: 49
[1]: 194 <--------- space is 194/160 here? Unicode bytes indicate that space should be the 160. What is the 194 then?
[2]: 160
[3]: 48
[4]: 50
[5]: 51
[6]: 32
[7]: 66
[8]: 121
[9]: 116
[10]: 101
[11]: 115
System.Text.Encoding.UTF8.GetBytes("1 023 Bytes")
{byte[11]}
[0]: 49
[1]: 32 <--------- space is 32 here
[2]: 48
[3]: 50
[4]: 51
[5]: 32
[6]: 66
[7]: 121
[8]: 116
[9]: 101
[10]: 115
System.Text.Encoding.Unicode.GetBytes(size1023)
{byte[22]}
[0]: 49
[1]: 0
[2]: 160 <----------- 160,0 here
[3]: 0
[4]: 48
[5]: 0
[6]: 50
[7]: 0
[8]: 51
[9]: 0
[10]: 32
[11]: 0
[12]: 66
[13]: 0
[14]: 121
[15]: 0
[16]: 116
[17]: 0
[18]: 101
[19]: 0
[20]: 115
[21]: 0
System.Text.Encoding.Unicode.GetBytes("1 023 Bytes")
{byte[22]}
[0]: 49
[1]: 0
[2]: 32 <----------- 32,0 here
[3]: 0
[4]: 48
[5]: 0
[6]: 50
[7]: 0
[8]: 51
[9]: 0
[10]: 32
[11]: 0
[12]: 66
[13]: 0
[14]: 121
[15]: 0
[16]: 116
[17]: 0
[18]: 101
[19]: 0
[20]: 115
[21]: 0
Run Code Online (Sandbox Code Playgroud)
问题:这怎么可能?
Jon*_*eet 12
我怀疑你当前的文化正在使用一个有趣的"千位"分隔符--U + 00A0,这是一个不间断的空格字符.这不是一个完全不合理的千位分隔符,说实话......这意味着你不应该得到这样的文字显示:
The size of the file is 1
023 bytes.
Run Code Online (Sandbox Code Playgroud)
相反,你会得到
The size of the file is
1 023 bytes.
Run Code Online (Sandbox Code Playgroud)
在我的盒子上,我得到了"1,023".您希望您的FormatSize方法使用当前文化还是特定文化?如果它是当前的文化,你应该让你的单元测试指定文化.我有几个用于此的包装器方法:
internal static void WithInvariantCulture(Action action)
{
WithCulture(CultureInfo.InvariantCulture, action);
}
internal static void WithCulture(CultureInfo culture, Action action)
{
CultureInfo original = Thread.CurrentThread.CurrentCulture;
try
{
Thread.CurrentThread.CurrentCulture = culture;
action();
}
finally
{
Thread.CurrentThread.CurrentCulture = original;
}
}
Run Code Online (Sandbox Code Playgroud)
所以我可以跑:
WithInvariantCulture(() =>
{
// Body of test
};
Run Code Online (Sandbox Code Playgroud)
等等
如果你想测试你得到的确切字符串,你可以使用:
Assert.AreEqual("1\u00A0023 Bytes", size1023);
Run Code Online (Sandbox Code Playgroud)