c# - string.Format 返回的 .NET 字符串中的空格与源代码中声明的空格不匹配 - 多种表示形式?

标签 c# .net string

string.Format 返回的字符串似乎使用了一些奇怪的编码。与源代码中声明的字符串中包含的空格相比,格式字符串中包含的空格使用不同的字节值表示。

下面的测试用例演示了这个问题:

[Test]
public void FormatSize_Regression() 
{
  string size1023 = FileHelper.FormatSize(1023);
  Assert.AreEqual("1 023 Bytes", size1023);
}

失败:

    String lengths are both 11. Strings differ at index 1.
    Expected: "1 023 Bytes"
    But was:  "1 023 Bytes"
    ------------^

FormatSize method:

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)));
}

在 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

问题:这怎么可能?

最佳答案

我怀疑您当前的文化正在使用一个有趣的“千位”分隔符 - U+00A0,这是一个不间断的空格字符。老实说,这并不是一个完全不合理的千位分隔符……这意味着您不应该显示这样的文本:

The size of the file is 1
023 bytes.

相反你会得到

The size of the file is
1 023 bytes.

在我的盒子上,我得到的是“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;
    }            
}

所以我可以运行:

WithInvariantCulture(() =>
{
    // Body of test
};

等等

如果你想测试你得到的字符串,你可以使用:

Assert.AreEqual("1\u00A0023 Bytes", size1023);

关于c# - string.Format 返回的 .NET 字符串中的空格与源代码中声明的空格不匹配 - 多种表示形式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1476068/

相关文章:

c# - Linq 返回 IEnumerable<MyObject>,如何返回 MyListObject?

c# - 增加一个 int++ 不会超过 1

c# - 如何在 ASP.Net 中加密文件并在 Silverlight 中解密?

c# - 获取带有文件夹 ID 的子文件 - 客户端对象模型

c# - x :Static in UWP XAML

python - 列表中要 float 的字符串

java - 关于检查字符串中某些字符的 stringChecker 的想法?

c# - 防止nhibernate中的Sql注入(inject)

c# - 如何从谓词中调用 TryParse

java - 文本分词器 - 从文本中提取单词和位置