c# - 转换通用 Span到特定的实例化(例如 Span) 如果它在运行时实际上是那种类型
问题描述
考虑以下 C# 代码:
using System;
public static class C
{
public static int[] TryGetIntArray<T>(T[] x)
{
if (x is int[] arr) // ok
return arr;
return Array.Empty<int>();
}
public static Span<int> TryGetIntSpan<T>(Span<T> x)
{
if (x is Span<int> span) // An expression of type 'Span<T>' cannot be handled by a pattern of type 'Span<int>'.
return span;
return Span<int>.Empty;
}
}
这个想法是如果参数在运行时实际上是该类型,则将参数作为Span<T>
(在这种情况下, )的特定特化返回;Span<int>
否则,只返回一个空跨度。我们可以看到这种方法适用于数组,但会因 span 而失败。是否也有解决方法可以使用跨度来执行此操作?
解决方案
如果可以添加where T : struct
,则有一种方法:
public static Span<int> TryGetIntSpan<T>(Span<T> x)
where T : struct
{
if (typeof(T) == typeof(int))
return MemoryMarshal.Cast<T, int>(x);
return Span<int>.Empty;
}
否则,这是另一种方式:
public static Span<int> TryGetIntSpan<T>(Span<T> x)
{
if (typeof(T) == typeof(int))
return MemoryMarshal.CreateSpan(ref Unsafe.As<T, int>(ref MemoryMarshal.GetReference(x)), x.Length);
return Span<int>.Empty;
}
它解构和重建跨度,因为你不能只使用Unsafe.As
它,因为Span
它是一个ref
结构,因此它不能用作类型参数。
检查被if (typeof(T) == typeof(int))
JIT 优化掉了。
推荐阅读
- php - 谷歌验证码 v2。我的表格不起作用
- javascript - 将 react-router-dom 的链接传递到外部库
- c# - Windows 服务无法启动 - 错误 1053
- flutter - Material Widget 有什么用?
- installation - 在本地安装 Eclipse CHe 时遇到问题
- java - 当存根返回存根时,初始化失败时存根
- java - 获取 org.hibernate.HibernateException:未配置 CurrentSessionContext
- pdf - SSRS 报告在转换为 PDF 时添加额外页面
- r - 使用 ggplotly() 时包装轴标签
- automation - 在 Discord 上自动发送消息(在后台)