假设我有一个排序函数定义如下:
public void Sort<T>(IList<T> Array)
where T : IComparisonOperators<T, T, bool>
{
//cool nerdy stuff
}
我希望该函数也能够作用于跨度。例如,如果我运行以下代码:
int[] array = new int[] {0, 3, 1, 2};
Span<int> span = new(array, 1, 2);
Sort(span);
foreach (int value in array)
Console.WriteLine(value);
控制台会输出:
0
1
3
2
因为数组的中间部分将按升序排序,而数组中跨度之外的部分将保持不变。
但是,
Span<T>
不实现IList<T>
,因为IList<T>
包含Insert
和RemoveAt
函数,而Span<T>
不支持这些函数。
我的排序函数只需要读取和写入数组,而不需要改变它的长度。我不需要
Insert
和 RemoveAt
函数,因此不想为两种不同类型创建完全相同代码的两个副本。
这引出了我的问题。
IList<T>
和 Span<T>
是否实现了可用于列表访问的通用接口?如果没有,最简单的解决方法是什么? Memory<T>
和新的 Tensor<T>
怎么样?
任何信息将不胜感激!
谢谢!
定义以下接口:
public interface IIndexed<T>
{
T this[int Index] { get; set; }
}
然后,编辑您的函数以使用您刚刚创建的界面,而不是
IList<T>
:
public void Sort<T>(IIndexed<T> Array)
where T : IComparisonOperators<T, T, bool>
{
//cool nerdy stuff
}
虽然对于未由类型实现的接口不存在隐式转换,但只要接口中的所有函数与类型中的函数一致,就确实存在显式转换。因此,可以让用户自己进行显式转换,或者简单地为他们添加以下三个重载:
public void Sort<T>(Span<T> Array)
where T : IComparisonOperators<T, T, bool>
=> Sort((IIndexed<T>)Array);
public void Sort<T>(Memory<T> Array)
where T : IComparisonOperators<T, T, bool>
=> Sort((IIndexed<T>)Array);
public void Sort<T>(IList<T> Array)
where T : IComparisonOperators<T, T, bool>
=> Sort((IIndexed<T>)Array);
耶!快乐编码!