2 votes

C# Retourner un type privé dans une fonction protégée où le type privé sera accessible à toutes les classes enfant.

J'ai deux classes, BaseO y PrivateO définis dans une autre classe, Overflow . BaseO est une classe publique, et PrivateO est privé. J'ai également une classe enfant à BaseO appelé ChildO qui est également public.

Maintenant, dans BaseO Je veux définir une fonction protégée protected Private0 getPrivate(); qui ChildO1 peut accéder. Mais cela n'est pas autorisé, car getPrivate a une accessibilité différente de celle de PrivateO .

Je comprends pourquoi c'est un problème, si quelqu'un devait hériter BaseO de l'extérieur Overflow ils doivent avoir accès à PrivateO ce qui n'est pas le cas.

J'ai contourné le problème pour l'instant en utilisant des objets et des casts, mais j'aimerais le faire plus correctement. Existe-t-il un moyen de spécifier que BaseO n'est pas destiné à être hérité de l'extérieur de l'UE. Overflow ?

internal est une idée, mais j'aimerais que cela fonctionne même lorsque le code n'est pas dans une assemblée différente.

J'ai accès à .NET 4.5 et C# 5, mais toute version plus récente serait également intéressante.

Exemple de code :

public static class Overflow
{
    private class PrivateO
    {
        public int foo;
    }

    public class BaseO
    {
        protected PrivateO GetPrivate() // inconsistent accessibility
        {
            return new PrivateO();
        }
    }

    public class ChildO : BaseO
    {
        private int foo;
        public ChildO()
        {
            this.foo = GetPrivate().foo; // <- desired behavior
        }
    }
}

Edit : Notez que le code d'exemple n'est que cela, un exemple. La vraie classe PrivateO est beaucoup plus complexe, et il ne s'agit pas seulement de récupérer un int. Elle renvoie également des classes de constructeurs privés et d'autres structures de données non triviales.

Edit 2 : Modifié Overflow à une classe statique pour souligner qu'elle est dans ce cas utilisée plus comme un espace de nom que comme une classe instanciable.

0voto

Neil Points 1235

Fournir une propriété accédante pour la propriété privée/protégée :

class Overflow
{
    private class PrivateO
    {
        public int foo;
    }

    public class BaseO
    {       
        PrivateO privateO = new PrivateO();
        public int PrivateFoo => privateO.foo;
    }

    public class ChildO : BaseO
    {
        private int foo;
        public ChildO()
        {
            this.foo = PrivateFoo;
        }
    }

}

0voto

InBetween Points 6162

Si Base0 n'a jamais besoin d'être instancié de l'extérieur et tous les types d'exécution seront des types dérivés tels que Child0 vous pouvez restreindre l'héritage aux types imbriqués :

public class BaseO
{   
    //private ctor avoids anyone extending this class
    //outside Base0 
    private Base0 { }   
    PrivateO privateO = new PrivateO();
    public int PrivateFoo => privateO.foo;

    public class ChildO : BaseO
    {
        private int foo;
        public ChildO()
        {
            this.foo = PrivateFoo;
        }
    }
}

Maintenant vous pouvez :

var child0 = new Overflow.Base0.Child0();

Mais vous ne pouvez faire aucune des deux choses suivantes à l'extérieur Overflow :

class anotherChild0: Overflow.Base0 { }
var base0 = new Overflow.Base0(); //potentially problematic

Si vous avez réellement besoin d'autoriser var base0 = new Overflow.Base0(); à l'extérieur de Overflow alors vous n'avez pas de chance, vous ne pouvez pas avoir le beurre et l'argent du beurre. Base0 et qu'elle n'est pas scellée, alors il pourra en hériter.

Dans ce cas, vos meilleures options sont :

  1. Vivre avec l'autorisation de l'héritage uniquement à l'intérieur d'une même assemblée ( internal constructeur)
  2. Ne pas exposer Base0 y Child0 à l'extérieur de Overflow exposer une interface IBase0
  3. Effectuez une vérification de l'exécution et supprimez toute classe qui appelle Base0() de l'extérieur de l'assemblage. YUCK ! (Je ne sais pas pourquoi je suggère même cela).

-1voto

MikeS Points 1492

Vous pourriez rendre la classe protégée et l'intégrer dans BaseO :

class Overflow
{

    public class BaseO
    {
        protected class PrivateO
        {
            public int foo;
        }

        protected PrivateO GetPrivate() 
        {
            return new PrivateO();
        }
    }

    public class ChildO : BaseO
    {
        private int foo;
        public ChildO()
        {
            this.foo = GetPrivate().foo; // <- desired behavior
        }
    }
}

-1voto

Robin Bennett Points 2982

Existe-t-il un moyen de spécifier que BaseO n'est pas destiné à être hérité de l'extérieur d'Overflow ?

Je pense que c'est ce que "Scellé est pour.

Lorsqu'il est appliqué à une classe, le modificateur scellé empêche d'autres classes d'en hériter.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X