Sponsored By Aspose - File Format APIs for .NET

Aspose are the market leader of .NET APIs for file business formats – natively work with DOCX, XLSX, PPT, PDF, MSG, MPP, images formats and many more!

Interface Re-Implementation Bug in 2.0 Runtime

Came across an interesting bug the other day in the MS newsgroups, it appears to be a bug in the 2.0.50727.42 release of the runtime. If this issue is affecting you, you can either use the updated 2.0.50727.97 revision of the runtime which seems to have this issue resolved or you can avoid the situation as I will show below.

The following C# code will illustrate the issue.

    using System;

    namespace InterfaceMapTest {

        class MyApp {

            static void Main(string[] args) {

                MyControl obj = new MyControl();

                obj.Paint();

                ((IControl)obj).Paint();

                IControl iControl = (IControl) obj;

                iControl.Paint();

            }

        }

        public interface IControl {

            void Paint();

        }

        public class Control : IControl {

            public virtual void Paint() {

                Console.WriteLine("Control.Paint");

            }

             void IControl.Paint() {

                Console.WriteLine("Control.IControl.Paint");

            }

        }

        public class MyControl : Control, IControl {

        }

    }

Listing 1: Code shows bug in 2.0.50727.42 version of runtime

C:\>C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\csc.exe foo.cs
Microsoft (R) Visual C# 2005 Compiler version 8.00.50727.42

for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727
Copyright (C) Microsoft Corporation 2001-2005. All rights reserved.

C:\>foo
Control.Paint
Control.Paint
Control.Paint

This code should print Control.IControl.Paint the second two calls. This worked properly in version 1.x of the framework (and in later revisions of 2.0).  At first I thought the C# compiler might be getting a bit confused but after a quick look with reflector I came received the following IL.

     .entrypoint
     .maxstack 1
     .locals init (
           [0] ConsoleApplication21.InterfaceMapTest.MyControl control1,
           [1] ConsoleApplication21.InterfaceMapTest.IControl control2)
     L_0000: nop
     L_0001: newobj instance void
ConsoleApplication21.InterfaceMapTest.MyControl::.ctor()
     L_0006: stloc.0
     L_0007: ldloc.0
     L_0008: callvirt instance void
ConsoleApplication21.InterfaceMapTest.Control::Paint()
     L_000d: nop
     L_000e: ldloc.0
     L_000f: callvirt instance void
ConsoleApplication21.InterfaceMapTest.IControl::Paint()
     L_0014: nop
     L_0015: ldloc.0
     L_0016: stloc.1
     L_0017: ldloc.1
     L_0018: callvirt instance void
ConsoleApplication21.InterfaceMapTest.IControl::Paint()
     L_001d: nop
     L_001e: ret

Listing 2: IL of main method

Which is correct, the ILASM’ed version of the same IL when run in 2.0.50727.97 will work properly (thanks to Bart De Smet for verifying this). Basically what it happening is that the runtime is getting confused by the re-implementation of the interface on the derived class. It only seems to happen when the same signature method on the base is virtual as well. If you run into this problem you may be able to not re-implement the interface on the derived class and the issue will go away. As this item has already been fixed I guess it just needs to be released so there is no feedback you can click through to vote etc.

This entry was posted in Uncategorized. Bookmark the permalink. Follow any comments here with the RSS feed for this post.

One Response to Interface Re-Implementation Bug in 2.0 Runtime

  1. Greg says:

    what makes this particularly nasty is when you are dealing with 1.x code that happens to be run in the context of the 2.0 runtime.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>