C#中如何将从IntPtr取回的对象转换为原类型?
解决方案
情况1:明确知道原始字典类型
如果已经确定对象是Dictionary<int, string>,直接强转即可,这是最简单高效的方式:
var handle2 = GCHandle.FromIntPtr(ptrObj); var objDict = handle2.Target; // 直接强转成具体类型 var myDict = (Dictionary<int, string>)objDict; int count = myDict.Count; // 正常调用Count属性 // 用完记得释放句柄,避免内存泄漏 handle2.Free();
情况2:不知道具体泛型参数,但知道是Dictionary
可以借助非泛型的IDictionary接口(所有泛型Dictionary<TKey,TValue>都实现了这个接口),不用明确泛型参数就能访问通用成员:
var handle2 = GCHandle.FromIntPtr(ptrObj); var objDict = handle2.Target; var myDict = (IDictionary)objDict; int count = myDict.Count; // 获取元素数量 string value = (string)myDict[1]; // 按键取值,需手动转换类型 handle2.Free();
情况3:完全不知道对象类型(极端场景)
用反射来读取属性或调用方法,虽然性能略差,但适合完全无类型信息的场景:
var handle2 = GCHandle.FromIntPtr(ptrObj); var objDict = handle2.Target; // 反射获取Count属性 Type dictType = objDict.GetType(); int count = (int)dictType.GetProperty("Count").GetValue(objDict); // 反射调用TryGetValue方法 object[] args = new object[] { 2, null }; bool success = (bool)dictType.GetMethod("TryGetValue").Invoke(objDict, args); if (success) { string value = (string)args[1]; } handle2.Free();
情况4:用泛型方法封装(代码更简洁)
可以写一个泛型工具方法来统一处理对象取回,调用时指定类型即可:
public static T GetObjectFromIntPtr<T>(IntPtr ptr) { using var handle = GCHandle.FromIntPtr(ptr); return (T)handle.Target; } // 使用示例 var myDict = GetObjectFromIntPtr<Dictionary<int, string>>(ptrObj); int count = myDict.Count;
关键注意事项
- 必须在使用完
GCHandle后调用Free(),否则会造成内存泄漏。 - 确保跨模块时,原始字典的类型(比如
Dictionary<int,string>)在两个模块中都能访问到(例如定义在共享类库中)。
内容的提问来源于stack exchange,提问作者ben yu
相关产品推荐
相关产品推荐

