由于 Span 和 IList 缺乏共同基础导致函数重复

问题描述 投票:0回答:1

假设我有一个排序函数定义如下:

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>
怎么样?

任何信息将不胜感激!

谢谢!

c# arrays .net-core inheritance interface
1个回答
0
投票

定义以下接口:

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);

耶!快乐编码!

© www.soinside.com 2019 - 2024. All rights reserved.