C# .NET Unexpected Typing - Expanded foreach explanation -


as refactoring code morning, noticed weird behavior. iterating on collection of type a. declaration , usage of enumerable split (i declaring , defining variable using linq, iterating on later via foreach). however, when changed type of enumerable ienumerable<a> ienumerable<b>, left foreach following enumerable of type ienumerable<b>.

ienumerable<b> enumerable = someenumerableofb     foreach(a in enumerable) 

following contrived example of behavior found:

    ienumerable<ienumerable> enumerables = enumerable.range(1, 5).select(x => new list<int> { x });     foreach (stringcomparer in enumerables) //this compiles     {         //do here     }      foreach (int in enumerables) //this doesn't compile     {         //do here     }      ienumerable<stringbuilder> stringbuilders = enumerable.range(1, 5).select(x => new stringbuilder(x.tostring()));     foreach (filestream sb in stringbuilders) //this doesn't compile     {         //do here                     } 

i surprised see first 1 compile. can explain why works? assume has fact ienumerable of interface, can't explain it.

according algorithm described section §15.8.4. of specification, compiler expand foreach following:

{     ienumerator<ienumerable> e = ((ienumerable<ienumerable>)(x)).getenumerator();      try     {         stringcomparer v;          while (e.movenext())         {             v = (stringcomparer)(ienumerable)e.current; // (*)             // here         }         }          {         // dispose of e     } } 

the line i've marked asterisk reason why compiles first , not second. valid cast because can have subclass of stringcomparer implements ienumerable. change to:

v = (int)(ienumerable)e.current; // (*) 

and doesn't compile, because not valid cast: int not implement ienumerable, , can't have subclasses.


Comments

Popular posts from this blog

php - What is the difference between $_SERVER['PATH_INFO'] and $_SERVER['ORIG_PATH_INFO']? -

fortran - Function return type mismatch -

queue - mq_receive: message too long -