.NET如何确定字符的Unicode类别?

6
我在使用.NET Reflector查看mscorelib.dll时,发现了Char类。我一直想知道像Char.isLetter这样的方法是如何实现的。我预期会有一个巨大的测试列表,但是通过深入挖掘,我发现了一个非常简短的代码来确定Unicode类别。然而,这段代码使用了某种表格和一些位移操作。有人可以解释一下这是如何实现的,或者给我指点一些资源吗?
编辑:这里是代码。它在System.Globalization.CharUnicodeInfo中。
internal static unsafe byte InternalGetCategoryValue(int ch, int offset)
{
    ushort num = s_pCategoryLevel1Index[ch >> 8];
    num = s_pCategoryLevel1Index[num + ((ch >> 4) & 15)];
    byte* numPtr = (byte*) (s_pCategoryLevel1Index + num);
    byte num2 = numPtr[ch & 15];
    return s_pCategoriesValue[(num2 * 2) + offset];
}

s_pCategoryLevel1Index 是一个 short* 类型的变量,而 s_pCategoryValues 则是一个 byte* 类型的变量。

这两个变量都是在 CharUnicodeInfo 的静态构造函数中创建的:

 static unsafe CharUnicodeInfo()
{
    s_pDataTable = GlobalizationAssembly.GetGlobalizationResourceBytePtr(typeof(CharUnicodeInfo).Assembly, "charinfo.nlp");
    UnicodeDataHeader* headerPtr = (UnicodeDataHeader*) s_pDataTable;
    s_pCategoryLevel1Index = (ushort*) (s_pDataTable + headerPtr->OffsetToCategoriesIndex);
    s_pCategoriesValue = s_pDataTable + ((byte*) headerPtr->OffsetToCategoriesValue);
    s_pNumericLevel1Index = (ushort*) (s_pDataTable + headerPtr->OffsetToNumbericIndex);
    s_pNumericValues = s_pDataTable + ((byte*) headerPtr->OffsetToNumbericValue);
    s_pDigitValues = (DigitValues*) (s_pDataTable + headerPtr->OffsetToDigitValue);
    nativeInitTable(s_pDataTable);
}

这里是UnicodeDataHeader。

internal struct UnicodeDataHeader
{
    // Fields
    [FieldOffset(40)]
    internal uint OffsetToCategoriesIndex;
    [FieldOffset(0x2c)]
    internal uint OffsetToCategoriesValue;
    [FieldOffset(0x34)]
    internal uint OffsetToDigitValue;
    [FieldOffset(0x30)]
    internal uint OffsetToNumbericIndex;
    [FieldOffset(0x38)]
    internal uint OffsetToNumbericValue;
    [FieldOffset(0)]
    internal char TableName;
    [FieldOffset(0x20)]
    internal ushort version;
}

注意:我希望这不会违反任何许可证。如果有违规,我将删除代码。


你能上传反编译的代码吗?并非每个人都拥有 Reflector。 - Scott M.
5
没有 Reflector 的 .NET 开发人员? :P - Shoban
没关系,我经常使用它 :) 我只是想有些人可能没有它。 - Scott M.
2个回答

2
基本信息存储在charinfo.nlp中,作为资源嵌入在mscorlib.dll中,在运行时加载。关于该文件的详细信息可能只有微软知道,但可以说它可能是一种查找表格。 编辑 根据MSDN的说明
这个枚举是基于Unicode标准第5版。有关更多信息,请参阅Unicode字符数据库中的“UCD文件格式”和“常规类别值”子主题。

它不是嵌入式的,而是一个链接资源。使用/linkresource编译器选项。我知道这是一个随机且无聊的细节。 - Hans Passant
@Hans Passant,我当然是指“嵌入了链接”的意思。你相信我,对吧? - Chris Haas
是的,我也发现了。可惜我找不到以可读格式打开这个charinfo.nlp文件的方法。目前我的.NET知识有限,而谷歌只知道自然语言处理... - subb

1

看起来像某种B树。

优点是一堆区域都可以指向同一个“字符未知”块,而不需要为每个可能的Char值在数组中拥有唯一元素。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接