【问题标题】:C# - T type, array, list indexingC# - T 类型、数组、列表索引
【发布时间】: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 访问数据。不过,这不是今天的选择。

标签: c# arrays methods


【解决方案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 创建数据的副本,所以没有帮助
猜你喜欢
  • 2013-05-05
  • 2011-12-28
  • 2016-11-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多