c# - Implementation of WhereListIterator.ToList() -
in piece of code like
list<int> foo = new list<int>() { 1, 2, 3, 4, 5, 6 }; ienumerable<int> bar = foo.where(x => x % 2 == 1); bar of type system.linq.enumerable.wherelistiterator<int> due deferred execution. since implements ienumerable<int> possible convert list<int>using tolist(). however, have been unable identify parts of code run when tolist() called. using dotpeek decompiler , first time attempting such thing, correct me if made mistakes on way.
i describe found far below (all assemblies version 4.0.0.0):
enumerable.wherearrayiterator<tsource>implemented in fileenumerable.csof namespacesystem.linqin assemblysystem.core. class neither definestolist()nor implementienumerable<tsource>. implementsenumerable.iterator<tsource>located in same file.enumerable.iterator<tsource>implementienumerable<tsource>.tolist()extension mewthod located inenumerable.cs. null checking , calling constructor oflist<tsource>argument.list<t>defined in filelist.csof namespacesystem.collections.genericin assemblymscorlib. constructor calledtolist()has signaturepublic list(ienumerable<t> collection). once again null checks , casts argumenticollection<t>. if collection has no elements, creates new list of empty array, otherwise usesicollection.copyto()method create new list.icollection<t>defined inmscorlib\system.collections.generic\icollection.cs. implementsienumerablein generic , non-generic form.
this stuck. neither enumerable.wherearrayiterator<tsource> nor enumerable.iterator<tsource> implement icollection, somewhere, cast has happen , unable locate code run when copyto() called.
i think you're getting confused as operator. it's safe cast. it's equivalent this, bit faster:
myendtype x = null; if (myvarwithas myendtype) x = (myendtype)myvarwithas; now, let's @ code again now.
public list(ienumerable<t> collection) { if (collection == null) throwhelper.throwargumentnullexception(exceptionargument.collection); icollection<t> collection1 = collection icollection<t>; if (collection1 != null) { int count = collection1.count; if (count == 0) { this._items = list<t>._emptyarray; } else { this._items = new t[count]; collection1.copyto(this._items, 0); this._size = count; } } else { this._size = 0; this._items = list<t>._emptyarray; foreach (t obj in collection) this.add(obj); } } as can see, in if checks if it's null. if it's null, means not icollection<t>, then goes else. else set default, , then adds in manually. when pass in ienumerable<t> not icollection<t> (like in example) go through else path.
Comments
Post a Comment