views:

132

answers:

1

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);
    }
}
+1  A: 

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
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
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
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
@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