【发布时间】: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_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;
}
注意:我希望这不会破坏任何许可证。如果是这样,我将删除代码。
【问题讨论】:
-
能发一下反编译的代码吗?不是每个人都有反射器
-
.net 开发者没有反射器? :P
-
不用担心,我一直都在使用它 :) 我只是想有些人可能没有它。