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()
?关于列表的相同方法:我们可以为列表编写单个方法,如果需要数组,只需在它之后返回内部列表的数组。@AlexJoukovskyCopyToArray(new int[data.Count])
肯定更快,原因与您的SelectToArray
更快相同。XyzToList
方法可以共享大量的实现,但是您需要将这些方法的签名添加到Enumerable
,这会使已经很大的接口更加膨胀代码>比数据更好。选择(x=>x.IntProperty).ToArray()?关于列表的相同方法:我们可以为列表编写单个方法,如果需要数组,只需在它之后返回内部列表的数组。@AlexJoukovskyCopyToArray(new int[data.Count])
肯定更快,原因与您的SelectToArray
更快相同。XyzToList
方法可以共享大量实现,但是您需要将这些方法的签名添加到可枚举的
,这将使已经很大的接口更加膨胀。