Visibilité de méthodes dans une classe interne

Visibilité de méthodes dans une classe interne - C#/.NET managed - Programmation

Marsh Posté le 08-11-2007 à 18:00:55    

Hello,
 
Je me pose plein de questions existentielles depuis que j'ai constaté qu'il est possible de compiler le code suivant:  
 

Code :
  1. internal class A
  2. {
  3.    public void Func()
  4.    {
  5.       // Fait des choses
  6.    }
  7. }


A priori je ne vois pas comment on peut utiliser la méthode Func() en dehors de l'assembly si la classe n'est pas visible. Du coup Func() n'a absolument aucun intérêt à être public, non ?
 
La question est de savoir si le compilateur ne devrait pas plutôt interdire ce genre de visibilité contradictoire. Ou est-ce qu'il y aurait une utilisation possible de ce genre de structure ?


Message édité par PowerKiKi le 08-11-2007 à 18:05:11
Reply

Marsh Posté le 08-11-2007 à 18:00:55   

Reply

Marsh Posté le 09-11-2007 à 10:18:40    

Le "public" sur ta fonction ne signifie pas du tout que tu le rends public pour tout ton programme...
 
Les access modifier sont hérités, donc c'est le modifier le plus restrictif dans ta déclaration qui s'applique.
 
Mais laisser public sur ta fonction, c'est garantir que tu ne vient pas altérer la permission définir sur ta classe... Si demain tu décide de passer ta classe en public, t'aura l'air bien con si tout dedans est en internal, tu seras vachement avancé...

Reply

Marsh Posté le 09-11-2007 à 12:08:51    

MagicBuzz a écrit :

Le "public" sur ta fonction ne signifie pas du tout que tu le rends public pour tout ton programme...
 
Les access modifier sont hérités, donc c'est le modifier le plus restrictif dans ta déclaration qui s'applique.


Je trouve la question de PowerKiKi pertinente, je trouve ça dangereux de permettre ce genre de chose.
 
Dans cet exemple ma méthode publique 'A.Func()' est quand même accessible depuis l'extérieur de l'assembly bien que ma classe soit "internal" :
 

Code :
  1. public interface : IA
  2. {
  3.    void Func();
  4. }
  5. internal class A : IA
  6. {
  7.    public void Func()
  8.    {
  9.       // Fait des choses
  10.    }
  11. }


 
Donc en lisant ma classe 'A' je ne peux pas dire si 'A.Func()' est accessible depuis l'extérieur de l'assembly ou non !
Aurais-tu de la documentation à propos de la visibilité en C# ?


Message édité par Ummon le 09-11-2007 à 12:12:20
Reply

Marsh Posté le 09-11-2007 à 12:12:20    

Tu peux me montrer un exemple ?
 
Parceque là, je vois pas en quoi Func() est visible depuis l'extérieur...
La classe étant internal, je vois pas comment tu peux y accéder...

Reply

Marsh Posté le 09-11-2007 à 12:15:33    

Tu ne peux pas instancier un A depuis l'extérieur, mais tes A sont implémentent correctement IA et peuvent donc être utilisés comme des IA depuis l'extérieur.

Reply

Marsh Posté le 09-11-2007 à 12:18:07    

MagicBuzz a écrit :

Tu peux me montrer un exemple ?
 
Parceque là, je vois pas en quoi Func() est visible depuis l'extérieur...
La classe étant internal, je vois pas comment tu peux y accéder...


Bien sur :
 

Code :
  1. // définition de A et IA ici
  2. public static class Builder
  3. {
  4.    public static IA BuildIA()
  5.    {
  6.       return new A();
  7.    }
  8. }


 
Dans ce cas 'A.Func()' peut-être accessible depuis l'extérieur de l'assembly, ce qui n'a rien d'anormal.
Le cas anormal c'est de déclarer une méthode publique dans un classe "internal" alors que cette méthode ne peux pas être accédé depuis l'extérieur, c'est le cas montré par PowerKiKi.


Message édité par Ummon le 09-11-2007 à 12:21:14
Reply

Marsh Posté le 09-11-2007 à 12:20:28    

Code :
  1. namespace ClassLibrary1
  2. {
  3.    public interface IA
  4.    {
  5.        string Print(string chaine);
  6.    }
  7.  
  8.    internal class A : IA
  9.    {
  10.        public A() { }
  11.  
  12.        public string Print(string chaine)
  13.        {
  14.            return string.Format("¤{0}¤", chaine);
  15.        }
  16.    }
  17. }


 

Code :
  1. using ClassLibrary1;
  2.  
  3. namespace TestConsole
  4. {
  5.    class Program
  6.    {
  7.        static void Main(string[] args)
  8.        {
  9.            IA t = new A();
  10.            Console.WriteLine(t.Print("plop" ));
  11.            Console.ReadKey(true);
  12.        }
  13.    }
  14. }


 


Erreur 1 'ClassLibrary1.A' est inaccessible en raison de son niveau de protection C:\Users\MagicBuzz\Documents\Visual Studio 2005\Projects\TestConsole\TestConsole\Program.cs 30 24 TestConsole

Message cité 1 fois
Message édité par MagicBuzz le 09-11-2007 à 14:49:00
Reply

Marsh Posté le 09-11-2007 à 12:21:15    

Ah ouais, ok, en passant par B, effectivement.
 
Mais c'est donc dans B qu'on a pas l'info...
 
Deplus, pour moi y'a un problème de conception dans ce cas : si une classe hérite d'une interface ou classe donc la portée est plus importante, on sait que toutes les méthodes surchargées peuvent éventuellement être exposées avec la même portée que l'élément parent.
 
Par contre, seules les méthodes surchargées sont accessibles, tout le reste reste avec le niveau de protection défini par la classe héritée.


Message édité par MagicBuzz le 09-11-2007 à 12:35:43
Reply

Marsh Posté le 09-11-2007 à 14:36:46    

MagicBuzz a écrit :



Erreur 1 'ClassLibrary1.A' est inaccessible en raison de son niveau de protection C:\Users\Luc Golden\Documents\Visual Studio 2005\Projects\TestConsole\TestConsole\Program.cs 30 24 TestConsole



Tu plantes sur l'instanciation, pas l'appel. Rajoute une méthode public IA factory() { return new A(); } et ça sera bon. Tu fais ça typiquement pour ne pas exposer l'implémentation, quand elle n'est pas pertinente. Genre un iterator.


Message édité par Taz le 09-11-2007 à 14:57:31
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed