1

所以我想问:为什么我们只有返回可枚举的选择器?例如,我经常遇到必须修改数组的每个值的情况,例如:

int[] a = {1,2,3,4,5};
a = a.Select(x=>x*2).ToArray();

所以在这里我们得到一个可枚举的,只有在它之后我们才能将它转换回数组。我们可以尝试使用 Array.ForEach,但前提是我们可以修改源。但是如果我们有引用类型的数组并且不能修改它们,我们无论如何都应该写这样的东西

SomeClass[] a = FillSomeClassArray();
SomeClass[] b = a.Select(x=> ((SomeClass)x.Clone()).Modify()).ToArray();

就我而言,我正在使用我自己的课程

public static class CollectionHelper
{
    public static TResult[] SelectToArray<T, TResult>(this ICollection<T> source, Func<T, TResult> selector)
    {
        if (source == null)
            throw new ArgumentNullException("source");
        if (selector == null)
            throw new ArgumentNullException("selector");
        var result = new TResult[source.Count];
        int i = 0;
        foreach (T t in source)
        {
            result[i] = selector(t);
            i++;
        }
        return result;
    }
}

这里我们没有双重转换,当我们没有谓词时,我们知道结果的长度,我们应该使用这个信息。我知道 MS 不应该代替我做所有的工作,但是 afaik 它的功能标准已经足够了。

4

1 回答 1

1

SelectToArray添加到框架中的最大问题是一致性。如果添加SelectToArray,则还应添加以下各项:

  • CastToArray<T>
  • ConcatToArray<T>
  • RepeatToArray<T>
  • ReverseToArray<T>
  • SkipToArray<T>
  • OfTypeToArray<T>
  • TakeToArray<T>

虽然我们的主题是添加新方法,但在列表中添加相同的优化有什么问题?现在我们还需要

  • SelectToList<T>(类似于开始这一切的那个)
  • CastToList<T>
  • ConcatToList<T>
  • ......等等 - 我相信你明白了。

考虑到知道目标数组或目标列表的大小所带来的微不足道的节省,这种主要的重构是不切实际的。您可以使用以下简单方法实现相同的效果:

static T[] CopyToArray(
    this IEnumerable<T> source
,   T[] result
,   int pos = 0
,   int? lengthOrNull = null
) {
    int length = lengthOrNull ?? result.Length;
    foreach (var item in source) {
        if (pos > length) break;
        result[pos++] = item;
    }
    return result;
}

现在调用者可以将现有的 LINQ 功能与此方法结合起来,组成上述所有XyzToArray方法,如下所示:

IList<MyClass> data = ...
int[] res = data.Select(x => x.IntProperty).CopyToArray(new int[data.Count]);

您还可以将 LINQ 查询的结果写入现有数组的不同部分,如下所示:

IList<MyClass> data1 = ...
IList<MyClass> data2 = ...
int[] res = new int[data1.Count+data2.Count];
data1.Select(x => x.IntProperty).CopyToArray(res, 0, data1.Count);
data2.Select(x => x.IntProperty).CopyToArray(res, data1.Count, data2.Count);
于 2013-11-10T12:09:32.337 回答