Ben*_*hon 6 .net c# appdomain string-interning
我想枚举字符串实习池中的字符串.
也就是说,我想所有的实例列表s的string这样:
string.IsInterned(s) != null
Run Code Online (Sandbox Code Playgroud)
有谁知道这是否可能?
感谢 @HansPassant 的建议,我设法获取了程序集中的字符串文字列表。这与我最初想要的非常接近。
您需要使用读取程序集元数据并枚举用户字符串。这可以通过以下三种方法来完成IMetaDataImport:
[ComImport, Guid("7DAC8207-D3AE-4C75-9B67-92801A497D44")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IMetaDataImport
{
void CloseEnum(IntPtr hEnum);
uint GetUserString(uint stk, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] char[] szString, uint cchString, out uint pchString);
uint EnumUserStrings(ref IntPtr phEnum, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)]uint[] rStrings, uint cmax, out uint pcStrings);
// interface also contains 62 irrelevant methods
}
Run Code Online (Sandbox Code Playgroud)
要获取 的实例IMetaDataImport,您需要获取IMetaDataDispenser:
[ComImport, Guid("809C652E-7396-11D2-9771-00A0C9B4D50C")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[CoClass(typeof(CorMetaDataDispenser))]
interface IMetaDataDispenser
{
uint OpenScope([MarshalAs(UnmanagedType.LPWStr)]string szScope, uint dwOpenFlags, ref Guid riid, [MarshalAs(UnmanagedType.Interface)] out object ppIUnk);
// interface also contains 2 irrelevant methods
}
[ComImport, Guid("E5CB7A31-7512-11D2-89CE-0080C792E5D8")]
class CorMetaDataDispenser
{
}
Run Code Online (Sandbox Code Playgroud)
事情是这样的:
var dispenser = new IMetaDataDispenser();
var metaDataImportGuid = new Guid("7DAC8207-D3AE-4C75-9B67-92801A497D44");
object scope;
var hr = dispenser.OpenScope(location, 0, ref metaDataImportGuid, out scope);
metaDataImport = (IMetaDataImport)scope;
Run Code Online (Sandbox Code Playgroud)
其中location是程序集文件的路径。
之后,打电话EnumUserStrings()就很GetUserString()简单了。
这是一篇包含更多详细信息的博客文章,以及GitHub 上的演示项目。
| 归档时间: |
|
| 查看次数: |
454 次 |
| 最近记录: |