3

The code below generates a warning CS3006 "Overloaded method MyNamespace.Sample.MyMethod(int[])' differing only in ref or out, or in array rank, is not CLS-compliant".

Is this warning valid, i.e. is this genuinely not CLS-compliant? I'd have thought an explicit interface implementation would not count as an overload.

[assembly: CLSCompliant(true)]
namespace MyNamespace
{

    public class Sample : ISample
    {
        public void MyMethod(int[] array)
        {
            return;
        }

        void ISample.MyMethod(ref int[] array)
        {
            this.MyMethod(array);
        }
    }

    public interface ISample
    {
        void MyMethod([In] ref int[] array);
    }
}
Joe
  • 122,218
  • 32
  • 205
  • 338
  • That is interesting. I don't have an answer, but I'll try to find out... IMO, it shouldn't be an error. – Marc Gravell May 22 '09 at 11:13
  • BTW, I've tried it in .NET 4.0, and it behaves the same. – Marc Gravell May 22 '09 at 11:20
  • "I'll try to find out" - great thanks. The use case for this is to have a ComVisible interface (where array parameters must be ref) without having ref parameters for .NET clients. – Joe May 22 '09 at 11:35
  • This looks like a compiler bug. I'll run it by the bug triage team, but I would not expect this to be fixed for C# 4.0. Thanks for bringing it to my attention. – Eric Lippert May 22 '09 at 16:12
  • "This looks like a compiler bug." I'd appreciate confirmation of this one way or the other. A fix isn't important, but I want to know if I should handle this by suppressing the compiler warning with a #pragma or by marking the class as CLSCompliant(false) – Joe May 22 '09 at 16:29

1 Answers1

2

CLS compliance only applies to the visible part of your class. Therefore, you'd think that the ref int[] is not public and therefore not relevant. But it is visible, through the interface.

The users of your code know that Sample provides void MyMethod(int[]). They also know that it implements ISample which provides void MyMethod(ref int[]). Therefore, I believe it is in fact not CLS-Compliant.


EDIT: Eric Lippert has commented on the original question that he believes this is in fact a compiler bug and that the original code is CLS-Compliant.


This, however, is valid:

[assembly: CLSCompliant(true)]
namespace MyNamespace
{
    public class Sample : ISample, ISample2
    {
        void ISample.MyMethod(ref int[] array)
        {
        }

        void ISample2.MyMethod(int[] array)
        {
        }
    }

    public interface ISample
    {
        void MyMethod(ref int[] array);
    }

    public interface ISample2
    {
        void MyMethod(int[] array);
    }
}

That is because CLS defines that two interface may define conflicting methods with the same name or signature and the compiler must know how to tell the difference - but again, only when the conflict is between two interfaces.

configurator
  • 40,828
  • 14
  • 81
  • 115
  • Thanks. "Therefore, I believe it is in fact not CLS-Compliant." - I don't see why this is a logical conclusion to your syllogism. Can you point me at a definition of CLS-compliance that makes the distinction between these cases? – Joe May 22 '09 at 15:04
  • Well I read the specification at http://msdn.microsoft.com/en-us/library/12a7a7h3.aspx . My reasoning is based on the fact that both types are visible to the calling assembly and it says that "CLS rules apply to those parts of a type that are exposed outside the defining assembly." – configurator May 22 '09 at 18:08
  • But if you consider an explicitly-implemented public interface to be "part of a type that is exposed outside the defining assembly", then the same reasoning would apply to two explicitly-implemented public interfaces - so both or neither of your examples should be CLS-compliant. However see the comment from Eric Lippert to the original question - it appears that this is CLS-compliant and the warning is a compiler bug. – Joe May 29 '09 at 10:11
  • @Joe, the case of two explicitly-implemented public interfaces is explicitly defined in the specification, so that would be CLS-compliant no matter if the case in question is. However, Eric Lippert is probably more informed than I am and I trust he is correct. – configurator May 29 '09 at 11:30