使用反射清空所有代表

时间:2013-07-24 21:19:25

标签: c# reflection delegates

我有一些代码:

private static st_createInstance        createInstance;
private static st_destroyInstance       destroyInstance;
private static st_getVersionId          getVersionId;
private static st_getVersionString2     getVersionString2;

//...

[UnmanagedFunctionPointer (CallingConvention.StdCall)]
private delegate IntPtr st_createInstance ();

[UnmanagedFunctionPointer (CallingConvention.StdCall)]
private delegate void st_destroyInstance (IntPtr pHandle);

//...

现在如何使用反射将所有这些代理置空? (Idk如何比较具有委托类型的字段)。

编辑:我想以简单的方式将所有这些都归零,比如foreach循环。不想指定每个字段名称。

2 个答案:

答案 0 :(得分:2)

如果type是委托字段所在的对象类型,请尝试以下方法:

var fields = type.GetFields(BindingFlags.Static | BindingFlags.NonPublic);

fields = fields.Where(f => f.FieldType.BaseType == typeof(System.MulticastDelegate));

foreach (FieldInfo fi in fields)
{
    fi.SetValue(null, null);
}

null中的SetValue表示它是静态字段,第二个字段用于将字段值设置为null

答案 1 :(得分:1)

这强烈暗示了XY问题。当OP没有解释为什么他需要做某事时,总是一个问题。当您尝试使用[DllImport]属性执行pinvoke marshaller所做的工作时,您会编写此类代码。

如果这是准确的,那么请注意,将这些委托对象设置为null几乎没有意义,即使它们是静态的。它们实际上是指 thunk ,这是一小段自动生成的代码,它们在非托管代码和托管代码之间进行编组。通常它不仅仅是一个简单的JMP指令,当需要重新调整堆栈帧时,它会变得更复杂。

委托对象本身需要一小部分GC堆,只有32个字节。你会想避免编写使用反射的代码来摆脱~36个字节,在任何时间或空间都没有收益。代码已经大于您发布的内存。更不用说真正的成本了,你维护这段代码。

考虑删除初始化这些委托的代码。几乎从来没有需要,pinvoke marshaller已经非常擅长这样做了。你只需要帮助它找出在哪里找到DLL,有比使用LoadLibrary()更好的方法。例如,请检查this answer