Reputation: 2880
I was checking article, https://learn.microsoft.com/en-us/archive/blogs/ericlippert/closing-over-the-loop-variable-considered-harmful
while(e.MoveNext())
{
int m; // INSIDE
m = (int)(int)e.Current;
funcs.Add(()=>m);
}
I searched about it, but didn't find why in m = (int)(int)e.Current;
its cast twice? I did check but both had same result and
((int)(int)e.Current).GetType() = Int32
((int)e.Current).GetType() = Int32
(e.Current).GetType() = Int32
Upvotes: 0
Views: 103
Reputation: 45101
It is really just a typo (yes, this happens even to Eric).
What i already seen in code is a double cast with two types, because otherwise it would fail. Like this example:
double? nullableDouble = 3;
int myInteger = (int)(double)nullableDouble;
Upvotes: 0
Reputation: 4104
Explanation is in page 7 of Q/A
Pavel Minaev [MSFT] 15 Nov 2009 11:15 PM
@Brad: according to the definition of foreach in the language spec, there are two types involved: element type (which is normally the type of Current property of the enumerator), and iteration variable type (which is the type you explicitly specify in foreach, or same as element type if you use "var"). The associated line of the expansion of foreach is this:
v = (V)(T)e.Current;
So far as I can see, the (T) cast will almost always be a no-op, because it will correspond to type of Current. Seemingly the only case where this isn't so is when you're iterating over an array (the spec requires the use of IEnumerable over IEnumerable in that case, and element type is derived not from Current, but from array type).
I wonder why it wasn't simply redefined to use IEnumerable for arrays as well (which would remove the need to special-case that, as well as the cast) - so far as I can see, the change wouldn't be observable to the user...
Upvotes: 2