【问题标题】:How does .NET determine the Unicode category of a character?.NET 如何确定字符的 Unicode 类别?
【发布时间】:2011-02-25 03:13:24
【问题描述】:

我在使用 .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_pCategoryLevel1Indexshort*s_pCategoryValuesbyte*

两者都是在 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;
}

注意:我希望这不会破坏任何许可证。如果是这样,我将删除代码。

【问题讨论】:

  • 能发一下反编译的代码吗?不是每个人都有反射器
  • .net 开发者没有反射器? :P
  • 不用担心,我一直都在使用它 :) 我只是想有些人可能没有它。

标签: c# .net unicode character


【解决方案1】:

基本信息存储在charinfo.nlp 中,它作为资源嵌入在mscorlib.dll 中并在运行时加载。该文件的细节可能只有 Microsoft 知道,但只要说它可能是某种方式的查找表就足够了。

编辑

According to MSDN:

此枚举基于 Unicode 标准 5.0 版。有关详细信息,请参阅 Unicode 字符数据库中的“UCD File Format”和“General Category Values”子主题。

【讨论】:

  • 它不是嵌入的,它是一个链接资源。 /linkresource 编译器选项。一个随机而无聊的细节,我知道。
  • @Hans Passant,“嵌入”当然是指“嵌入链接”。你相信我,对吧?
  • 是的。我也发现了。遗憾的是,我找不到以可读格式打开此 charinfo.nlp 的方法。目前我对 .NET 的了解有限,Google 只知道自然语言处理......
【解决方案2】:

这看起来像是某种 b 树。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-07-16
    • 1970-01-01
    • 1970-01-01
    • 2016-09-07
    • 2012-11-27
    • 2018-12-16
    • 1970-01-01
    • 2013-07-19
    相关资源
    最近更新 更多