I just read an interesting article called Getting too cute with c# yield return
It made me wonder what the best way is to detect whether an IEnumerable is an actual enumerable collection, or if it's a state machine generated with the yield keyword.
For example, you could modify DoubleXValue (from the article) to something like:
private void DoubleXValue(IEnumerable<Point> points)
{
if(points is List<Point>)
foreach (var point in points)
point.X *= 2;
else throw YouCantDoThatException();
}
Question 1) Is there a better way to do this?
Question 2) Is this something I should worry about when creating an API?
Best Answer
Your question, as I understand it, seems to be based on an incorrect premise. Let me see if I can reconstruct the reasoning:
The problem is that the second premise is false. Even if you could detect whether or not a given IEnumerable was the result of an iterator block transformation (and yes, there are ways to do that) it wouldn't help because the assumption is wrong. Let's illustrate why.
All right, we have four methods. S1 and S2 are automatically generated sequences; S3 and S4 are manually generated sequences. Now suppose we have:
The result for S1 and S4 will be 0; every time you enumerate the sequence, you get a fresh reference to an M created. The result for S2 and S3 will be 100; every time you enumerate the sequence, you get the same reference to M you got the last time. Whether the sequence code is automatically generated or not is orthogonal to the question of whether the objects enumerated have referential identity or not. Those two properties -- automatic generation and referential identity -- actually have nothing to do with each other. The article you linked to conflates them somewhat.
Unless a sequence provider is documented as always proffering up objects that have referential identity, it is unwise to assume that it does so.