C#:如何将null传递给期望ref的函数?
我有以下function:
public static extern uint FILES_GetMemoryMapping( [MarshalAs(UnmanagedType.LPStr)] string pPathFile, out ushort Size, [MarshalAs(UnmanagedType.LPStr)] string MapName, out ushort PacketSize, ref Mapping oMapping, out byte PagesPerSector);
我想这样称呼:
FILES_GetMemoryMapping(MapFile, out size, MapName, out PacketSize, null, out PagePerSector);
不幸的是,我不能在需要类型ref Mapping
的字段中传递null
而且没有强制转换我已尝试修复此问题。
有什么建议?
我假设Mapping是一个结构? 如果是这样,您可以使用具有不同签名的两个版本的FILES_GetMemoryMapping()
原型。 对于要传递null
的第二个重载,请将参数设置为IntPtr
并使用IntPtr.Zero
public static extern uint FILES_GetMemoryMapping( [MarshalAs(UnmanagedType.LPStr)] string pPathFile, out ushort Size, [MarshalAs(UnmanagedType.LPStr)] string MapName, out ushort PacketSize, IntPtr oMapping, out byte PagesPerSector);
电话示例:
FILES_GetMemoryMapping(MapFile, out size, MapName, out PacketSize, IntPtr.Zero, out PagePerSector);
如果Mapping实际上是一个类而不是一个结构,只需将值设置为null,然后再将其传递给它。
无法传递null
的原因是因为C#编译器对ref
参数给予了特殊处理。 任何ref
参数都必须是可以传递给您正在调用的函数的引用。 由于您要传递null
因此编译器拒绝允许此操作,因为您没有提供该函数期望具有的引用。
你唯一真正的选择是创建一个局部变量,将其设置为null
,然后传入。编译器不允许你做更多的事情。
一种方法是创建一个虚拟变量,将其赋值为null,然后传入。
Mapping oMapping = null; FILES_GetMemoryMapping(MapFile, out size, MapName, out PacketSize, ref oMapping, out PagePerSector);
虽然@ JaredPar的答案无疑是正确的答案,但还有另一个答案: unsafe
代码和指针:
unsafe { Mapping* nullMapping = null; FILES_GetMemoryMapping( MapFile, out size, MapName, out PacketSize, ref *nullMapping, // wat? out PagePerSector); }
看起来它应该在运行时失败,但它不会,因为ref
和*
相互抵消,而ref *nullMapping
的结果值是空指针,这是FILES_GetMemoryMapping()
将为该参数接收的。
这可能不是一个好主意 ,但它是可能的 。
也许它不完全是理想的答案,但是如果在调用函数时需要传递null作为参数,请考虑对该函数进行重载,省略您尝试设置为null的变量的forms参数。
例如,假设您有一个如下所示的函数:
public void MyFunction(string x, int y, ref string z) {...};
您希望能够为参数z传递null。 尝试创建一个新的MyFunction
重载,看起来像这样:
public void MyFunction(string x, int y) {...};
这种方法不适合每个人的需求,但这是另一种可能的解决方案。