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&lt;T&gt; 机制;您应该能够在大多数数组和连续列表上创建Span&lt;T&gt;,并且它允许就地ref 访问数据。不过,这不是今天的选择。 【参考方案1】:

最简单的方法可能是为某些T 设置参数IList&lt;T&gt;,因为IList&lt;T&gt; 具有索引器支持并且数组和列表都实现IList&lt;T&gt;。请注意,您可能不需要在这里传递n,因为IList&lt;T&gt; 也有.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&lt;T&gt;,它会更喜欢内置的List&lt;T&gt;.Sort(),这将更有效 - 但它会编译 适用于任何 IList&lt;T&gt; 类型。

【讨论】:

我当然应该注意,编写自己的排序算法不一定是个好主意。 List&lt;T&gt;.SortArray.Sort 等是更好的选择。 哦...所以我可以像这样通过整个 int[] -> List&lt;int[]&gt; asd = new List&lt;int[]&gt;(); 但是如何通过列表? @SzabolcsMészáros var list = new List&lt;int&gt; 3, 4, 1, 5, 2 ; NormSort(list); System.Console.WriteLine(string.Join(",", list)); - 注意我不认为算法现在可以工作,但这是一个实现细节 注意,这只是我的问题和我的学校任务的一个例子。 @SzabolcsMészáros 您通常不会使用数组列表——即“锯齿状”。在这种情况下,您几乎肯定是指List&lt;int&gt;;数组是不可比较的,例如(你不能问一个数组是否是&gt;另一个数组)。【参考方案2】:

使用 IEnumerable 你可以拥有所有类型的集合:

public void NormSort<T>(ref IEnumerable<T> input, int n)
 ...

【讨论】:

不允许使用索引器 是的,但是你有 ElementAt(N) 或 ToArray() 然后使用索引器。 如果你使用ToArray,你将修改一个不同的枚举,所以排序将不起作用。 @Stefano 非常效率低下,并且打破了你不应该依赖可重复的枚举的意图,plus i> 可枚举没有改变值的机制,加上如果你设法它会破坏可枚举; ToArray 创建数据的副本,所以没有帮助

以上是关于C# - T 类型、数组、列表索引的主要内容,如果未能解决你的问题,请参考以下文章

C#索引器:在集合或数组中取出某一个元素 举例 _转

在 c# 中拥有一个采用任何类型的可索引列表的方法的最有效方法是啥

c# 语言 -- 数组

C# - 在for循环中使用相同的列表大小,索引超出了数组的范围[重复]

描述一下C#中索引器的实现过程,是否只能根据数字进行索引?

在索引处的 List<T> 中添加值的 C# 方法