我有一些性能关键的硬件互操作代码,出于优化原因(是的,我分析)将一个通用的struct参数作为ref
(即使它实际上并没有修改参数)然后使用System.Runtime.CompilerServices.Unsafe
类将其转换为可以传递给硬件驱动程序的指针。这是一个例子:
unsafe void DoPerformanceCriticalThing<T>(ref T myThing)
where T : struct
{
void* ptr = Unsafe.AsPointer(ref myThing);
// Give ptr to low-level hardware driver.
}
由于此代码(包括传递ptr
的硬件驱动程序)从未实际修改myThing
,因此ref
的存在具有误导性,我想要更改它到in
参数(在C#7.2中添加的功能)。但是,in
参数不能作为ref
参数传递,Unsafe
类不支持in
参数
所以我的问题是,有没有办法将ref T myThing
更改为in T myThing
并仍能获得指向它的指针?
答案 0 :(得分:1)
好吧,我终于弄清楚了如何使用C#7.3中的新'unmanaged' generic constraint来做到这一点。通过将这种新约束应用于通用类型,便可以声明该通用类型的指针并使用fixed
语句获取参数的地址:
unsafe void DoPerformanceCriticalThing<T>(in T myThing)
where T : unmanaged
{
fixed(T* ptr = &primitive)
{
// Give ptr to low-level hardware driver.
}
}
很明显,unmanaged
约束比struct
约束更严格,因为它可以防止类型包含对托管对象的任何引用,但是我怀疑在大多数情况下(包括我自己的所有情况) )在实践中不会有问题。