c# - How to tell if an IEnumerable<T> is subject to deferred execution ? -
I always believed that if I was selecting (x => ... )
The context of LINQ for the objects, then the new collection will be created immediately and will remain stable. I am not sure why I assumed it, and this is a very bad assumption, but I did it. I often .toList ()
not anywhere else but not in this case.
This code indicates that a simple 'selection' is subject to deferred execution:
var random = new random (); Var animal = new [] {"cat", "dog", "mouse"}; Var randomNumberOfAnimals = animals.Select (x => Math.floor (random.NextDouble (* 100) + "+ + + +" + "S"); Foreign currency (in the form of random number of pomegranate) {testContextInstance.WriteLine ("there are" + I); } Foreach (I am numbered atoms in random) {testContextInstance.WriteLine ("and now, there are" + i); }
This gives the following output (random function every time the archive repeats):
There are 75 cats, 28 dogs are 62 moles and now, There are 78 cats and now, here are 69 dogs and now 43 are mues. I have many places where I have a IEnumerable & lt; T & gt;
As a member of a class Often results of a LINQ query such as IEnumerable & lt; T & gt;
. Generally this does not create problems for me, but recently my code has got some place where it is more than just a display problem. In an attempt to check the places where I made this mistake, I can see if any particular IEnumerable & lt; T & gt;
type IQueryable
I think if the collection was 'suspended' or not, then I would have to tell it. It has been found that the calculator type created by the above operator is not System.Linq.Enumerable + WhereSelectArrayIterator` [System.String, System.String]
and IQueryable
I was seeing why this interface has inherited, and it has not been hereditary with anything that indicates that it is 'LINQ' exactly - so the basis on the collection type is tested There is no way to do it.
I am now putting .aArray ()
entirely now, but I have a mechanism to make sure that this problem is not in the future. Visual Studio knows how to do this because it gives a message about 'that the collection will be evaluated in detail to see the results. '
The best part is that:
Boole deferred =! Object. Reference Number (Random Number) Other Number. First (), random number study. Last ()); Edit: This works only when a new object is created with 'selection' and this is not a common solution. It has not been recommended! This solution had a little tongue in the cheek.
Many people are trapped in the defiant execution of LINQ, you are not alone.
The approach I have taken to avoid this problem is as follows:
Methods of parameters - Usage IEnumerable & lt; T & gt;
Unless more specific interfaces are required.
Local Variables - Usually at the point where I am creating LINQ, I will know whether lazy evaluation is possible.
Class Members - IEnumerable & lt; T & gt; Never use
, always use list & lt; T & gt;
.
Properties - IEnumerable & lt; T & gt; Use
, and convert to storage in setter.
Public IEnumerable & lt; Person & gt; People come back {people; } Set {people = value.ToList (); }} Private listing & lt; People & gt; People;
In theoretical cases where this approach will not work, I have not run into one yet, and I have been using LINQ expansion methods enthusiastically since late beta.
BTW: I'm curious that you ToArray (); toList () instead of
- There is a very good API in the lists, and
Updates : Some commentators have correctly told that a theoretical performance benefit of arrays So, I do not have "... (almost) any performance cost" to my statement.
Update 2 : I've written some code, which has some micro-benchmarking There is a difference in the performance between the arrays and lists. On my laptop, and in my specific benchmark, the difference is approximately 5ns (that is nanos seconds) per reach, I think there are cases where 5 pars per side will be suitable to save ... but I I have never come near one. I had my test increased to 100 million iterations before long enough to measure
respectively.
Comments
Post a Comment