C# list.Take(100.ToList()与list.GetRange(0100)的比较 列出与会者=新建列表(); foreach。。。 //错误:“电子邮件地址数组中的目标用户太多” //超过100名与会者。因此,仅以前100名与会者为例。 如果(Attendes.Count>100)Attendes=Attendes.GetRange(0100); //或 如果(Attendes.Count>100)Attendes=Attendes.Take(100.ToList();
因为我的列表总是超过100个,而且总是取前100个,所以最明显的差异(评估策略、跳过的可能性、出错的可能性)并不是很有趣C# list.Take(100.ToList()与list.GetRange(0100)的比较 列出与会者=新建列表(); foreach。。。 //错误:“电子邮件地址数组中的目标用户太多” //超过100名与会者。因此,仅以前100名与会者为例。 如果(Attendes.Count>100)Attendes=Attendes.GetRange(0100); //或 如果(Attendes.Count>100)Attendes=Attendes.Take(100.ToList();,c#,linq,C#,Linq,因为我的列表总是超过100个,而且总是取前100个,所以最明显的差异(评估策略、跳过的可能性、出错的可能性)并不是很有趣 但也许您可以解释一下“在源代码列表中创建一系列元素的浅拷贝”的确切含义。它听起来确实很昂贵,比Take更贵,是吗?唯一的区别是它比Take(n).ToList()更高效,因为它已经知道新列表的大小,而LINQ方法不知道它的大小 因此,枚举序列并使用双倍算法将项目添加到一个新列表中,并连续增加支持数组列表。GetRange可以预先创建具有正确初始大小的适当列表,然后使用它将源列
但也许您可以解释一下“在源代码列表中创建一系列元素的浅拷贝”的确切含义。它听起来确实很昂贵,比Take更贵,是吗?唯一的区别是它比
Take(n).ToList()
更高效,因为它已经知道新列表的大小,而LINQ方法不知道它的大小
因此,枚举序列并使用双倍算法将项目添加到一个新列表中,并连续增加支持数组<代码>列表。GetRange可以预先创建具有正确初始大小的适当列表,然后使用它将源列表的子集复制到新列表[]中。以下是实现:
List<AttendeeInfo> attendees = new List<AttendeeInfo>();
foreach ...
// Error: "There are too many target users in the email address array"
// for more than 100 attendees. So take the first 100 attendees only.
if(attendees.Count > 100) attendees = attendees.GetRange(0,100);
// or
if(attendees.Count > 100) attendees = attendees.Take(100).ToList();
此外,这只是:
public static IEnumerable<TSource> Take<TSource>(this IEnumerable<TSource> source, int count)
{
if (source == null)
{
throw Error.ArgumentNull("source");
}
return TakeIterator<TSource>(source, count);
}
private static IEnumerable<TSource> TakeIterator<TSource>(IEnumerable<TSource> source, int count)
{
if (count > 0)
{
foreach (TSource iteratorVariable0 in source)
{
yield return iteratorVariable0;
if (--count == 0)
{
break;
}
}
}
}
您可以立即注意到,相比于
Take
,GetRange
要便宜得多,它要快得多。看看这个:
public List(IEnumerable<T> collection)
{
if (collection == null)
{
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.collection);
}
ICollection<T> is2 = collection as ICollection<T>;
if (is2 != null)
{
int count = is2.Count;
if (count == 0)
{
this._items = List<T>._emptyArray;
}
else
{
this._items = new T[count];
is2.CopyTo(this._items, 0);
this._size = count;
}
}
else
{
this._size = 0;
this._items = List<T>._emptyArray;
using (IEnumerator<T> enumerator = collection.GetEnumerator())
{
while (enumerator.MoveNext())
{
this.Add(enumerator.Current);
}
}
}
}
var list=Enumerable.Range(0,1000).ToList();
var stopwatch=新秒表();
秒表。开始();
对于(var i=0;iList.Take(100).ToList(),如果您不知道列表中的元素数,则更合适。如果小于100,则只取可用的元素。使用此选项更灵活。
另一方面,List.GetRange(0100)假设列表中的元素数超过100。但是,您会得到此错误***
偏移量和长度超出了数组的界限或计数更大
大于从索引到源结尾的元素数
收藏
***。
如果元素数小于指定的范围
对我来说,List.Take(100).ToList()更一般,因为它不限制使用。在Take
和GetRange
之间有一个微小的差别。Take将惰性地进行评估,直到你强迫它评估为ToList()
。这会改变行为
考虑伪代码
var list = Enumerable.Range(0, 1000).ToList();
var stopwatch = new Stopwatch();
stopwatch.Start();
for(var i=0; i<1000000; i++)
{
var c = list.GetRange(0, 100);
}
Console.WriteLine(stopwatch.Elapsed);
stopwatch.Restart();
for (var i = 0; i < 1000000; i++)
{
var c = list.Take(100).ToList();
}
Console.WriteLine(stopwatch.Elapsed);
List myList=newlist(){1,2,3,4,5,6};
IEnumerable otherList=myList.Take(3);/{1,2,3};
myList.Removate(0,3);
//myList={4,5,6}
//otherList={4,5,6}
现在将此示例更改为以下代码
List<int> myList = new List<int>() {1,2,3,4,5,6};
IEnumerable<int> otherList = myList.Take(3); // {1,2,3};
myList.RemoveRange(0,3);
// myList = {4, 5, 6}
// otherList = {4, 5, 6}
List myList=newlist(){1,2,3,4,5,6};
IEnumerable otherList=myList.Take(3.ToList();/{1,2,3};
myList.Removate(0,3);
//myList={4,5,6}
//otherList={1,2,3}
执行ToList()
可以根据下一步使用的操作更改Take或GetRange的行为。使用GetRange总是比较容易,因为它不会导致任何未知错误
GetRange也是有效的。您省略了核心功能List
的构造函数。此外,如果您只计算代码行,方法的效率也不明显。我知道您在示例中使用了列表,但需要注意的是,如果您使用的是数组,您可以执行以下操作:int[]source={1,2,3,4,5,6};IList Attendeers=new ArraySegment(source,2,source.Length-2);
它只是在数组周围创建一个轻包装,跳过前n个(本例中为2个)元素。
var list = Enumerable.Range(0, 1000).ToList();
var stopwatch = new Stopwatch();
stopwatch.Start();
for(var i=0; i<1000000; i++)
{
var c = list.GetRange(0, 100);
}
Console.WriteLine(stopwatch.Elapsed);
stopwatch.Restart();
for (var i = 0; i < 1000000; i++)
{
var c = list.Take(100).ToList();
}
Console.WriteLine(stopwatch.Elapsed);
List<int> myList = new List<int>() {1,2,3,4,5,6};
IEnumerable<int> otherList = myList.Take(3); // {1,2,3};
myList.RemoveRange(0,3);
// myList = {4, 5, 6}
// otherList = {4, 5, 6}
List<int> myList = new List<int>() {1,2,3,4,5,6};
IEnumerable<int> otherList = myList.Take(3).ToList(); // {1,2,3};
myList.RemoveRange(0,3);
// myList = {4, 5, 6}
// otherList = {1, 2, 3}