【问题标题】:C#: Different string encoding on attribute vs. constantC#:属性与常量的不同字符串编码
【发布时间】:2021-04-07 12:13:04
【问题描述】:

我正在为一个旨在删除无效代码点(例如孤立代理对)的函数编写测试。 但是,我发现代理对的编码方式有所不同,具体取决于我编写测试的方式。

虽然此版本的测试通过:

        [TestCategory("UnitTest")]
        [TestMethod]
        public void RemoveOrhpanedSurrogatePair()
        {
            var input = "\uDDDD1975";
            var cleanText = input.ReplaceInvalidCodePoints();

            Assert.AreEqual(input.Length - 1, cleanText.Length);
            Assert.AreEqual("1975", cleanText);
        }

这个没有:

        [TestCategory("UnitTest")]
        [TestMethod]
        [DataRow("\uDDDD1975")]
        public void RemoveOrhpanedSurrogatePair(string input)
        {
            var cleanText = input.ReplaceInvalidCodePoints();

            Assert.AreEqual(input.Length - 1, cleanText.Length);
            Assert.AreEqual("1975", cleanText);
        }

查看调试器,第一个变体将字符串编码为"\uDDDD1975",但第二个变体生成"��1975",它显示为两个有效字符,而不是一个孤立的代理对。

【问题讨论】:

  • 可以用任何属性重现相同的行为dotnetfiddle.net/Aux1H7
  • 好像也是这样编译的sharplab.io/…
  • 我猜这是罗斯林的问题
  • 字符串是一个 unicode 字符数组。当输入不是有效字符时,任何事情都可能发生。
  • ECMA-335 CLI 规范在 I.24.2.4 中指出,#Userstring blob 的任何可访问部分都应仅包含有效的 UTF16。这适用于普通字符串。因此,这将无法验证。而对于 I.23.3 中的自定义属性,它只需要一串代码点。

标签: c# string unicode encoding


【解决方案1】:

我认为答案的线索可以在(除了)@jonskeet blog post 中找到。显然 C# 在任何地方都使用 UTF16 对字符串进行编码,except 在使用 UTF8 的属性 c'tors 中。编译器似乎看到这是一个孤立的代理对,并通过其 UTF8 值将其视为两个无效的 Unicode 字符。然后将它们替换为一对\uFFFD 字符(Unicode replacement character,用于在将二进制解码为文本时指示损坏的数据)。

[Description(Value)]
class Test
{
    const string Value = "\uDDDD";
 
    static void Main()
    {
        var description = (DescriptionAttribute)
            typeof(Test).GetCustomAttributes(typeof(DescriptionAttribute), true)[0];
        DumpString("Attribute", description.Description);
        DumpString("Constant", Value);
    }
 
    static void DumpString(string name, string text)
    {
        var utf16 = text.Select(c => ((uint) c).ToString("x4"));
        Console.WriteLine("{0}: {1}", name, string.Join(" ", utf16));
    }
}

将产生:

Attribute: fffd fffd
Constant: dddd

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-11-24
    • 1970-01-01
    • 1970-01-01
    • 2017-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-19
    相关资源
    最近更新 更多