Welcome to MSDN Blogs Sign in | Join | Help

Today's C# quiz - does this compile?

using System;
using System.Collections.Generic;

class Program
{
    static void Main(string[] args)
    {
        IEnumerable<Inter1> ienum1 = new Class1[] { new Class1() };
        foreach (Class2 c in ienum1)
        {
            Console.WriteLine(c);
        }
    }
}

public interface Inter1 { }
public class Class1 : Inter1 { }
public class Class2 { }
Published Friday, November 16, 2007 1:11 PM by jmanning

Comments

# re: Today's C# quiz - does this compile?

Friday, November 16, 2007 3:02 PM by Hotmail User

No, it won't compile.

Class2 has no relation to Class1 or Inter1. c has to be either of type Class1 or Inter1 for this to compile.

# re: Today's C# quiz - does this compile?

Friday, November 16, 2007 3:05 PM by Hotmail User

Why is this question so simple? I was expecting questions that only C# MVPs can solve.

# re: Today's C# quiz - does this compile?

Friday, November 16, 2007 4:27 PM by jmanning

# csc temp.cs

Microsoft (R) Visual C# 2008 Compiler version 3.5.20921

for Microsoft (R) .NET Framework version 3.5

Copyright (C) Microsoft Corporation. All rights reserved.

# temp

Unhandled Exception: System.InvalidCastException: Unable to cast object of type 'Class1' to type 'Class2'.

  at Program.Main(String[] args)

Bonus question - why does it compile?

# re: Today's C# quiz - does this compile?

Friday, November 16, 2007 5:39 PM by hboyceiii

It's an interesting scenario...same thing happens in VS2k5.  My take on what's happening is IEnumerable<> : IEnumerable (non-generic).  the foreach macro is expanded to:

IEnumerator e = ienuml.GetEnumerator();

while(e.MoveNext())

{

Class2 current = e.Current as Class2;

//code in foreach

}

since IEnumerator isn't strongly-typed, the cast to class 2 is what's causing the exception.

And I didn't cheat (ILDasm or Reflector) either!!! ;-)

# re: Today's C# quiz - does this compile?

Friday, November 16, 2007 5:51 PM by hboyceiii

As an addendum to that, the Class1[] is really an instance of System.Array - not generic - implements IEnumerable; however, it's legit to cast to/from IEnumerable and IEnumerable<>.

Since you're casting from non-generic to generic, I guess the compiler can't resolve the types...and that's why it breaks...

[this time I did cheat and use ILDasm ;-)]

# Today's C# quiz - does this compile?

Friday, November 16, 2007 6:17 PM by Noticias externas

using System; using System.Collections.Generic; class Program { static void Main( string [] args) { IEnumerable&lt;Inter1&gt;

# re: Today's C# quiz - does this compile?

Friday, November 16, 2007 6:30 PM by jmanning

Good comments so far.  A couple more hints/tips:

- Foo[] (array of Foo) *does* implement IEnumerable[Foo] (the generic interface)

- the code would fail to compile if IEnum1 was IEnumerable[Class1] instead of IEnumerable[Inter1]

 - for those that think that it's just the IEnumerable (non-generic) implementation that gets this to work

# re: Today's C# quiz - does this compile?

Monday, November 19, 2007 5:54 PM by kdbond

It compiles because the foreach generates an iterator over types of the interface Inter1 and since the Interface is empty the signature of Class2 matches the interface even though it does not actually implement it.

# re: Today's C# quiz - does this compile?

Monday, November 19, 2007 7:48 PM by jmanning

Good try, but even if you add something to the interface and don't add it to Class2, the code still compiles - you can change the last 3 lines, for instance, to this and it still compiles.

public interface Inter1 { int MyProperty { get; } }

public class Class1 : Inter1 { public int MyProperty { get { return 0; } } }

public class Class2 { }

# re: Today's C# quiz - does this compile?

Wednesday, November 21, 2007 6:15 PM by jkingry

       foreach (Class2 c in ienum1)

       {

           Console.WriteLine(c);

       }

is equivalent to in this case to:

IEnumerator<Iter1> e = null;

try

{

 e = ienum1.GetEnumerator();

 while(e.MoveNext())

 {

   Class2 instance =  (Class2) e.Current;

   Console.WriteLine(instance);

 }

}

finally

{

 e.Dispose();

}

foreach includes an explicit cast.

# C# quiz answer - yes it compiles, and here's why

Saturday, November 24, 2007 12:29 AM by James Manning's blog

Got a few good comments to the quiz post , but nobody that commented got it right. I went ahead and sent

# C# quiz answer - yes it compiles, and here's why

Saturday, November 24, 2007 1:25 AM by Noticias externas

Got a few good comments to the quiz post , but nobody that commented got it right. I went ahead and sent

Anonymous comments are disabled
 
Page view tracker