As I recently learned myself , the foreach loop explicitly casts to the type of an elementary variable. This has been going on since C # 2.0, where generics were introduced.
List myList = getStringList(); foreach (string element in myList) {
Even if myList is just a List , and not shared, and therefore contains only objects, I know that it contains strings, and can just do this foreach loop, which will add an explicit conversion for me.
Enter the generics. Suddenly you no longer need it, but it is still part of the language.
List<string> myList = getStringList(); foreach (string element in myList) {
However, now this can have terrible pitfalls:
List<long> myLongList = getLongList(); foreach (int element in myLongList) {
This will not result in an error, no warning, and runtime exception. Despite the fact that I threw debts on ints without checking. There is a good chance that I just messed up my data. Uch. How to avoid this?
Using var , just like you.
List<long> myLongList = getLongList(); foreach (var element in myLongList) {
Now, regardless of the type of the list item, my element variable will have the same type. Hooray!
In cases where this is not warranted, when working with non-universal APIs such as XmlNode . When you request its child nodes, you are not getting a generic list. If you are now using var , the system does not know that this list contains only XmlNode instances. All he can do is really go a non-generic way and turn this var into an object .
In short, your first foreach works fine due to implicit explicit actuation (as I came to call it). The second of these fails, because without this translation, type information is missing, but object .