【发布时间】:2021-05-27 14:56:06
【问题描述】:
我正在编写一个基本库来试验 C# 硬件内在函数(System.Runtime.Intrinsics* 命名空间),并有一个可以支持任何“硬件”类型的方法(Byte、SByte...UInt64、@ 987654327@)
当尝试使用泛型签名时,编译器无法使用泛型并且无法选择正确的重载;例如:
public static unsafe void GenericSimd<T>(T value, ReadOnlySpan<T> span) where T : unmanaged
{
fixed (T* fixedSpan = span)
{
Vector128<T> vec0 = Vector128.Create(value); // CS1503, Cannot convert T to byte
Vector128<T> vec1 = Sse2.LoadVector128(fixedSpan); // CS1503, Cannot convert T* to byte*
}
}
参考:CS1503
我认为这是由于 unmanaged 约束允许其他非“硬件”类型(Decimal、enum 等),因此限制不足以保证存在适当的过载。
定义一个接口作为附加约束与unmanaged 一起使用也是不可行的,因为它需要部分内置类型。
有没有办法使用泛型来实现这个方法并避免为每种类型编写重载?
【问题讨论】:
-
dynamic可能会起作用,但如果您使用 SIMD,我假设您还没有准备好支付这笔开销 -
重载解析发生在编译时。由于不同的类型使用不同的
Create重载,编译器无法选择正确的 one 重载来调用此方法。为避免过多重复,我建议使用文本模板或新的源生成器,它们从您需要实现的固定类型列表中工作。 -
是的,如果可能的话,我宁愿避免使用
dynamic。不过,我没有考虑过源生成器,它应该可以正常工作。谢谢!
标签: c# .net-core intrinsics