C# - T 类型、数组、列表索引
Posted
技术标签:
【中文标题】C# - T 类型、数组、列表索引【英文标题】:C# - T type, array, list indexing 【发布时间】:2018-04-27 08:23:03 【问题描述】:我想写一个方法,我可以发送任何类型的[]
、List<>
...等。但是在代码中,当我使用 T 并且我想对输入数组、列表或任何内容进行索引时,错误会显示“无法将 []
的索引应用于‘T’类型的表达式”。有什么解决方案,或者我必须为数组、列表等编写单独的代码?
public void NormSort<T>(ref T input, int n)
for (int i = 0; i < n - 2; i++)
for (int j = 0; j < n - 1; j++)
if (Comparer<T>.Default.Compare(input[i], input[j]) > 0)
Swap<T>(input[i], input[j]);
public void Swap<T>(T item1, T item2)
var temp = item1;
item1 = item2;
item2 = temp;
那么输入[i],输入[j]在哪里,我得到了那个错误。
【问题讨论】:
作为参考,它看起来就像你习惯于使用 C/C++ 指针(这段代码散发出从基于指针的代码中提取出来的味道);您在这里尝试做的事情很好地映射到即将到来的Span<T>
机制;您应该能够在大多数数组和连续列表上创建Span<T>
,并且它允许就地ref
访问数据。不过,这不是今天的选择。
【参考方案1】:
最简单的方法可能是为某些T
设置参数IList<T>
,因为IList<T>
具有索引器支持并且数组和列表都实现IList<T>
。请注意,您可能不需要在这里传递n
,因为IList<T>
也有.Count
属性。所以:
public void NormSort<T>(IList<T> input)
int n = input.Count;
// ...
但是请注意,您的 Swap
方法不起作用;这不是通过-ref
,即使是:您不能通过 ref 传递索引器值 - 您需要单独获取和设置;也许:
public static void NormSort<T>(IList<T> input)
int n = input.Count;
var comparer = Comparer<T>.Default;
for (int i = 0; i < n - 1; i++)
for (int j = i; j < n; j++)
T x = input[i], y = input[j];
if (comparer.Compare(x, y) > 0)
input[i] = y;
input[j] = x;
请注意,这里更典型的实现是扩展方法:
public static void Sort<T>(this IList<T> input) ...
然后你可以使用:
myListOrArray.Sort();
作为一个很好的副作用,如果编译器知道它是List<T>
,它会更喜欢内置的List<T>.Sort()
,这将更有效 - 但它会编译 适用于任何 IList<T>
类型。
【讨论】:
我当然应该注意,编写自己的排序算法不一定是个好主意。List<T>.Sort
、Array.Sort
等是更好的选择。
哦...所以我可以像这样通过整个 int[] -> List<int[]> asd = new List<int[]>();
但是如何通过列表?
@SzabolcsMészáros var list = new List<int> 3, 4, 1, 5, 2 ; NormSort(list); System.Console.WriteLine(string.Join(",", list));
- 注意我不认为算法现在可以工作,但这是一个实现细节
注意,这只是我的问题和我的学校任务的一个例子。
@SzabolcsMészáros 您通常不会使用数组列表——即“锯齿状”。在这种情况下,您几乎肯定是指List<int>
;数组是不可比较的,例如(你不能问一个数组是否是>
另一个数组)。【参考方案2】:
使用 IEnumerable 你可以拥有所有类型的集合:
public void NormSort<T>(ref IEnumerable<T> input, int n)
...
【讨论】:
不允许使用索引器 是的,但是你有 ElementAt(N) 或 ToArray() 然后使用索引器。 如果你使用ToArray
,你将修改一个不同的枚举,所以排序将不起作用。
@Stefano 非常效率低下,并且打破了你不应该依赖可重复的枚举的意图,plus i> 可枚举没有改变值的机制,加上如果你设法它会破坏可枚举; ToArray 创建数据的副本,所以没有帮助以上是关于C# - T 类型、数组、列表索引的主要内容,如果未能解决你的问题,请参考以下文章
在 c# 中拥有一个采用任何类型的可索引列表的方法的最有效方法是啥