c# - C#:属性与常量的不同字符串编码
问题描述
我正在为一个旨在删除无效代码点(例如孤立代理对)的函数编写测试。但是,我发现代理对的编码方式有所不同,具体取决于我编写测试的方式。
虽然此版本的测试通过:
[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"
显示为两个有效字符,而不是一个孤立的代理对。
解决方案
我认为答案的线索可以在(除了)@jonskeet博客文章中找到。显然 C# 在任何地方都使用 UTF16 对字符串进行编码,除了在使用 UTF8 的 Attribute c'tors 中。编译器似乎看到这是一个孤立的代理对,并通过其 UTF8 值将其视为两个无效的 Unicode 字符。然后将它们替换为一对\uFFFD
字符(Unicode 替换字符,用于在将二进制解码为文本时指示损坏的数据)。
[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
推荐阅读
- discord.js - 自动删除用户反应
- android - Firebase 手机身份验证仅在发布模式下不启动 OTP,但即使在为发布模式添加 sha1 后也可以在调试模式下工作
- python - 训练 3dconv 神经网络失败;损失收敛于 .6931
- c# - 尝试输出字母等级
- combobox - wxpython - wx.EVT_COMBOBOX 事件和 GetSelection 方法:手动与用户触发
- c# - Web 部署发布到远程 IIS 后,ASP.NET Core 3.1 身份持久化 cookie 身份验证仍然失败
- c - C 编程:使用结构和函数来确定两个日期之间的天数
- forms - 颤振表单验证仅适用于第一次
- c++ - 尝试获取当前工作目录时出错:win32app.dll 未准备好
- c++ - 如何将各种类型的向量转换为 std::string?