You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 07:20:37