2009-05-22 4 views
3

Le code ci-dessous génère un avertissement CS3006 "Méthode surchargée MyNamespace.Sample.MyMethod (int []) 'différant uniquement par ref ou out, ou rang de tableau, n'est pas compatible CLS".L'avertissement CS3006 est-il valide dans ce cas?

Cet avertissement est-il valide, c'est-à-dire n'est-il pas conforme CLS? J'aurais pensé qu'une implémentation d'interface explicite ne compterait pas comme une surcharge.

[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); 
    } 
} 
+0

C'est intéressant. Je n'ai pas de réponse, mais je vais essayer de trouver ... OMI, ça ne devrait pas être une erreur. –

+0

BTW, je l'ai essayé dans. NET 4.0, et il se comporte de la même manière. –

+0

"Je vais essayer de trouver" - merci beaucoup. Le cas d'utilisation pour cela est d'avoir une interface ComVisible (où les paramètres du tableau doivent être ref) sans avoir de paramètres ref pour les clients .NET. – Joe

Répondre

2

La conformité CLS ne s'applique qu'à la partie visible de votre classe. Par conséquent, vous penseriez que le ref int[] n'est pas public et donc pas pertinent. Mais il est visible, à travers l'interface. Les utilisateurs de votre code savent que Sample fournit void MyMethod(int[]). Ils savent également qu'il implémente ISample qui fournit void MyMethod(ref int[]). Par conséquent, je crois que ce n'est pas conforme CLS.


EDIT: Eric Lippert a commenté la question initiale qu'il croit que c'est en fait un bug du compilateur et que le code d'origine est conforme CLS.


Ceci, cependant, est valable:

[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); 
    } 
} 

C'est parce que CLS définit que deux interface peut définir des méthodes contradictoires avec le même nom ou la signature et le compilateur doit savoir comment faire la différence - mais encore une fois, seulement lorsque le conflit est entre deux interfaces.

+0

Merci. "Par conséquent, je crois que ce n'est pas conforme CLS." - Je ne vois pas pourquoi c'est une conclusion logique à ton syllogisme. Pouvez-vous me signaler une définition de la conformité CLS qui fait la distinction entre ces cas? – Joe

+0

Eh bien, j'ai lu la spécification à http://msdn.microsoft.com/en-us/library/12a7a7h3.aspx. Mon raisonnement est basé sur le fait que les deux types sont visibles par l'assembly appelant et il dit que "les règles CLS s'appliquent aux parties d'un type qui sont exposées en dehors de l'assembly de définition." – configurator

+0

Toutefois, si vous considérez qu'une interface publique explicitement implémentée fait partie d'un type exposé en dehors de l'assembly de définition, le même raisonnement s'applique à deux interfaces publiques explicitement mises en œuvre. Les deux ou aucun de vos exemples ne doivent donc être CLS-conforme. Cependant, voir le commentaire d'Eric Lippert à la question initiale - il semble que ce soit conforme CLS et l'avertissement est un bug du compilateur. – Joe

Questions connexes