为什么用于Unicode属性测试的C#System.Char方法有两个重载?

时间:2016-06-08 19:06:08

标签: c# unicode char

methods of System.Char中,我们看到两种检查字符是否为符号的方法:

public static bool IsSymbol(string s, int index)
public static bool IsSymbol(char c)

同样适用于其他属性测试:IsLower,IsLetter等

为什么会出现这种重复?是否有理由更喜欢Char.IsSymbol(s, idx)而不是Char.IsSymbol(s[idx])

1 个答案:

答案 0 :(得分:11)

在表面上,两个重载似乎在功能上都相同,但是向下调用InternalGetUnicodeCategory将显示它们导致调用CharUnicodeInfo.GetUnicodeCateogry的不同重载。

string,int重载最终会在调用同一个InternalConvertToUtf32 char函数之前通过InternalGetUnicodeCategory进行UTF32转换。这解释了以UTF16编码字符解码代理对的可能性。

   internal static UnicodeCategory InternalGetUnicodeCategory(String value, int index) {
        Contract.Assert(value != null, "value can not be null");
        Contract.Assert(index < value.Length, "index < value.Length");

        return (InternalGetUnicodeCategory(InternalConvertToUtf32(value, index)));
    }

Check out the Conversion implementation here if you want.

为什么你可能会问这个问题?那么答案就是.Net支持文本元素。微软表示:

MSDN Documentation on Unicode Support for Surrogate Pairs

  

文本元素是一个文本单元,显示为单个字符,称为字素。文本元素可以是基本字符,代理项对,也可以是组合字符序列。

虽然我不相信IsSymbol函数及其亲属可以解码字形或组合字符序列,但是文本元素标注的原因是它们可以被定义为代理对,因此需要通过string,intIsSymbol(), IsLetter()重载进行解码...

这意味着通过char重载传递代理对会返回错误的结果,因为字符串中的字符可能是代理对。你不能假设一个16位编码代表一个字符,并且在所述索引处传递字符串的字符就可以做出这样的假设。

因为代理对可以用.Net中的字符串表示,所以如果你正在处理可以包含其中一个的字符串,那么IsSymbol(string s, int index)重载会是更合适的是为了涵盖其中一对存在的情况。

结果不同的具体示例是

string s = char.ConvertFromUtf32(128204); // ""

Debug.Assert(char.IsSymbol(s[0]) == char.IsSymbol(s, 0)); // Fails