Wrong overload being called

I have a class with two methods, one of which overrides a base class method:

public override void Write (byte[] b)
public void Write<T> (IList<T> b)

Then make the call:

byte[] bArray = new byte[] {1,2,3,4};
myClass.Write (bArray);

... but it is the Write (IList<T>) which gets called, even though Write (byte[]) is an exact match. This seems very wrong!

Full compilable example below:

using System;
using System.IO;
using System.Collections.Generic;

public class TestClass : BinaryWriter {
  public override void Write (byte[] b) {
    Console.WriteLine ("Write(byte[]) called");
  }
  public void Write<T> (IList<T> b) {
    Console.WriteLine ("Write(IList<T>) called");
  }
 }

 public class MainProgram {
   static void Main (string[] args) {
     TestClass tc = new TestClass();
     byte[] bArray = new byte[] {1,2,3,4};
     tc.Write (bArray);
   }
 }

Is this a framework bug




Answer this question

Wrong overload being called

  • kalai

    The problem with that is, FxCop analysis is done AFTER compilation; it won't know what C# code looked like during analysis.

  • Can-Ann

    I would think this is DEFINITELY a candidate for a Code Analysis warning, since this behaviour is going to surprise >90% of all programmers that see it!

    I'm going to go and suggest that in the FXCop forum.

  • Daniel Danilin

    I've escalated it to the C# team; we'll see what they say...

  • Patrick Travers

    That would have to a C# thing, as it's the C# compiler that translates the C# code into IL. I've moved the message to the C# language forum.

  • RabinLin

    Matthew Watson wrote:
    Ah, of course.

    Well, in that case it's a candidate for a compiler warning.
    I haven't had much luck with suggesting compiler warnings. But, it's worth a try; and at least it has to be acknowledged.

    Visual Studio and .NET Framework Feedback



  • Bjoern.Greiff

    There's currently a bit of debate about what's going on in this case. It appears (either erroneously or not) override-resolution rules are making your non-"override" methods take precedence, and since byte[] implements IList, your Write<T>(IList<T>) is being called.

    A workaround would be not to override the Write method with something that could be used with a byte[] parameter (in your case IList<T>; but IList, ICollection, and possibly ICloneable would cause the same problem).

    I'll add posts to this thread with updated information, as I receive it.



  • TheQuietShadow

    Ah, of course.

    Well, in that case it's a candidate for a compiler warning.

  • PamelaO

    Looks like a bug to me. You should report it at

    http://connect.microsoft.com/feedback/default.aspx SiteID=210

    (You have to register there to report bugs tho')

  • marco.ragogna

    This is not a bug.  It's how the C# language is supposed to handle overrides, based upon the current specification.

    Method invocation resolution works in several passes.  The first pass looks at only applicable, non-overridden, accessible methods in the type indicated by the method invocation.  Since, in your example, Write<T>(IList<T>) is the only method that fits that criteria, it is chosen as the method to call.

    [edit: this is covered by Member lookup in the the spec.; section 14.3]



  • Wrong overload being called