Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/visual-studio-2010/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么System.Linq.Enumerable中没有SelectToArray方法_C#_.net_Arrays_Linq_Collections - Fatal编程技术网

C# 为什么System.Linq.Enumerable中没有SelectToArray方法

C# 为什么System.Linq.Enumerable中没有SelectToArray方法,c#,.net,arrays,linq,collections,C#,.net,Arrays,Linq,Collections,所以我想问:为什么我们只有一个选择器返回一个可枚举的?例如,我经常遇到这样的情况,当我必须修改数组的每个值时,例如: int[] a = {1,2,3,4,5}; a = a.Select(x=>x*2).ToArray(); 所以这里我们得到了一个可枚举项,只有在它之后,我们才能将它转换回数组。 我们可以尝试使用Array.ForEach,但前提是我们可以修改源代码。但是,如果我们有一个引用类型数组,并且不能修改它们,那么无论如何我们应该编写这样的代码 SomeClass[] a =

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

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;
    }
}
公共静态类CollectionHelper
{
public static TResult[]SelectToArray(此ICollection源,Func选择器)
{
if(source==null)
抛出新的ArgumentNullException(“源”);
if(选择器==null)
抛出新的ArgumentNullException(“选择器”);
var result=new TResult[source.Count];
int i=0;
foreach(源中的T)
{
结果[i]=选择器(t);
i++;
}
返回结果;
}
}

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

在框架中添加
SelectToArray
的最大问题是一致性。如果添加
选择阵列
,还应添加以下各项:

  • CastToArray
  • concatotarray
  • RepeatToArray
  • ReverseToArray
  • skiptorarray
  • 类型数组的
  • TakeToArray
当我们讨论添加新方法时,向列表添加相同的优化有什么不对?现在我们也需要

  • 选择ToList
    (与启动它的列表类似)
  • CastToList
  • ConcatToList
  • 。。。等等,我相信你有这个想法
考虑到知道目标数组或目标列表的大小所节省的成本微乎其微,这样大规模的重构是不切实际的。您可以通过以下简单方法实现相同的效果:

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;
}
IList<MyClass> data = ...
int[] res = data.Select(x => x.IntProperty).CopyToArray(new int[data.Count]);
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);
您还可以将LINQ查询的结果写入现有数组的不同部分,如下所示:

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;
}
IList<MyClass> data = ...
int[] res = data.Select(x => x.IntProperty).CopyToArray(new int[data.Count]);
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);
IList数据1=。。。
IList数据2=。。。
int[]res=newint[data1.Count+data2.Count];
选择(x=>x.IntProperty).copytarray(res,0,data1.Count);
选择(x=>x.IntProperty).CopyToArray(res,data1.Count,data2.Count);

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

  • CastToArray
  • concatotarray
  • RepeatToArray
  • ReverseToArray
  • skiptorarray
  • 类型数组的
  • TakeToArray
当我们讨论添加新方法时,向列表添加相同的优化有什么不对?现在我们也需要

  • 选择ToList
    (与启动它的列表类似)
  • CastToList
  • ConcatToList
  • 。。。等等,我相信你有这个想法
考虑到知道目标数组或目标列表的大小所节省的成本微乎其微,这样大规模的重构是不切实际的。您可以通过以下简单方法实现相同的效果:

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;
}
IList<MyClass> data = ...
int[] res = data.Select(x => x.IntProperty).CopyToArray(new int[data.Count]);
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);
您还可以将LINQ查询的结果写入现有数组的不同部分,如下所示:

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;
}
IList<MyClass> data = ...
int[] res = data.Select(x => x.IntProperty).CopyToArray(new int[data.Count]);
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);
IList数据1=。。。
IList数据2=。。。
int[]res=newint[data1.Count+data2.Count];
选择(x=>x.IntProperty).copytarray(res,0,data1.Count);
选择(x=>x.IntProperty).CopyToArray(res,data1.Count,data2.Count);

btw,这里有ToList().ForEach()我想从源代码获取一个数组,只调用一个方法
ToList().ForEach
并不是更好,简单的
Select.ToArray()
等等,还有ToList().ForEach()我想从源代码获取一个数组,只调用一个方法
ToList().ForEach
并不是更好,简单的
Select.ToArray()
等等,只要你认为
data.Select(x=>x.IntProperty).copytarray(newint[data.Count])比数据更好。选择(x=>x.IntProperty).ToArray()
?关于列表的相同方法:我们可以为列表编写单个方法,如果需要数组,只需在它之后返回内部列表的数组。@AlexJoukovsky
CopyToArray(new int[data.Count])
肯定更快,原因与您的
SelectToArray
更快相同。
XyzToList
方法可以共享大量的实现,但是您需要将这些方法的签名添加到
Enumerable
,这会使已经很大的接口更加膨胀比数据更好。选择(x=>x.IntProperty).ToArray()?关于列表的相同方法:我们可以为列表编写单个方法,如果需要数组,只需在它之后返回内部列表的数组。@AlexJoukovsky
CopyToArray(new int[data.Count])
肯定更快,原因与您的
SelectToArray
更快相同。
XyzToList
方法可以共享大量实现,但是您需要将这些方法的签名添加到
可枚举的
,这将使已经很大的接口更加膨胀。