C# in Depth

Cover of C# in Depth
Order now (3rd edition)

Implicit casting in foreach loops over generic collections

Chapter 1: The changing face of C# development: 1.1.2

Created: 1/20/2008
Last updated: 1/20/2008

After changing the returned list of products from an ArrayList to a List<Product>, the book makes the following bold claim:

Similarly, the invisible cast in the foreach loop has gone. It’s hard to tell the difference, given that it’s invisible, but it really is gone. Honest. I wouldn’t lie to you. At least, not in chapter 1...

Well, it's sort of true and it sort of isn't. The compiler effectively converts the foreach loop into code which does contain a cast - but then it notices that the cast is just an identity conversion, so it optimizes it away from the compiled code.

In other cases, there will still be a cast in the compiled code. Consider this perfectly valid program:

using System;
using System.Collections.Generic;

class Test
{
    static void Main()
    {
        List<object> list = new List<object> { "This is a string" };
        
        foreach (string entry in list)
        {
            Console.WriteLine(entry);
        }
    }
}

In this case, there's a cast present in the compiled IL. If the list contains something other than a string, it will still compile but will fail at execution time.