Choisir quelle classe peut en instancier une autre [Résolu]

Whismeril 10530 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 14 décembre 2017 Dernière intervention - 12 nov. 2015 à 19:30 - Dernière réponse : Whismeril 10530 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 14 décembre 2017 Dernière intervention
- 13 nov. 2015 à 21:10
Bonsoir,

je me casse les dents sur ce problème depuis quelques jours.

J'ai besoin d'une classe static, qui initialise une liste d'une autre classe (Test).
Le reste du programme n'a accès qu'à une instance de cette liste via à accesseur.
Pour le reste du programme
  • les propriétés de Test doivent être en lecture seule.
  • il ne doit pas être possible d'instancier Test



Un exemple:
    public static class SeuleClasseOuOnPeutInitialiserTest
    {
        private static List<Test> tests;

        static SeuleClasseOuOnPeutInitialiserTest()
        {
            tests = new List<Test>();

            //Ici j'ai besoin de pouvoir ajouter des instances de Test dans la liste, avec des valeurs, mais que cela ne soit pas possible ailleurs.
        }

        public static Test MonTest(int index)
        {
            return tests[index];
        }

    }

    public class Test
    {
        public int Entier { get; private set; }

        public double Decimal { get; private set; }
    }


J'ai essayer de dériver SeuleClasseOuOnPeutInitialiserTest de Test, ça marche si SeuleClasseOuOnPeutInitialiserTest n'est pas static, mais je n'ai pas trouvé comment faire dans mon cas.

Existe t il un moyen pour qu'un constructeur ne soit visible que de SeuleClasseOuOnPeutInitialiserTest?

Ou une autre idée?

Merci d'avance.
Afficher la suite 

7 réponses

Répondre au sujet
Whismeril 10530 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 14 décembre 2017 Dernière intervention - 13 nov. 2015 à 10:31
+1
Utile
3
Merci à tous les deux,

La classe incorporée dans l'autre sens, le constructeur privé et le modificateur sealed (pour que personne ne puisse dériver la classe) et ça marche comme on me le demande.

Je poste le code d'exemple ce soir, c'est un peu casse c.... avec la tablette.
Cette réponse vous a-t-elle aidé ?  
Whismeril 10530 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 14 décembre 2017 Dernière intervention - 13 nov. 2015 à 20:24
Voila le code
    public sealed class Test
    {
        private Test(){}

        private Test(int entier, double decimale)
        {
            Entier = entier;
            Decimal = decimale;
        }

        public int Entier { get; protected set; }

        public double Decimal { get; protected set; }


        public static class SeuleClasseOuOnPeutInitialiserTest
        {
            private static List<Test> tests;

            static SeuleClasseOuOnPeutInitialiserTest()
            {
                tests = new List<Test>();
                tests.Add(new Test(1, 2.1));
                tests.Add(new Test {Entier = 2, Decimal= 2.3});
            }

            public static Test MonTest(int index)
            {
                return tests[index];
            }

        }


    }


Le seul petit inconvénient est que pour utiliser SeuleClasseOuOnPeutInitialiserTest il faut appeler Test. SeuleClasseOuOnPeutInitialiserTest
KX 15089 Messages postés samedi 31 mai 2008Date d'inscriptionModérateurStatut 14 décembre 2017 Dernière intervention - 13 nov. 2015 à 21:00
"Le seul petit inconvénient est que pour utiliser SeuleClasseOuOnPeutInitialiserTest il faut appeler Test. SeuleClasseOuOnPeutInitialiserTest"

En gros ça va te donner quoi ?

SeuleClasseOuOnPeutInitialiserTest initializer = new SeuleClasseOuOnPeutInitialiserTest();
Test test = initializer.MonTest(2);

Perso, ça ne me choque pas vraiment...
Après ça dépend ce que tu veux faire exactement, mais moi j'irais probablement encore plus loin en attribuant à Test une méthode static qui retourne une instance de SeuleClasseOuOnPeutInitialiserTest :

public static SeuleClasseOuOnPeutInitialiserTest BuildInitializer() {
    return new SeuleClasseOuOnPeutInitialiserTest();
}

Ce qui donnerait par exemple :

Test test = Test.BuildInitializer().MonTest(2);
Whismeril 10530 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 14 décembre 2017 Dernière intervention - 13 nov. 2015 à 21:10
J'ai bien dit que cet inconvénient est petit. ;-)!

En fait le vrai code contient, plusieurs méthodes static qui d'une façon ou d'une autre retourne un ou plusieurs éléments de la liste.

Pour l'extérieur, le comportement interne doit rester opaque, les champs en lecture seule et les classes non instanciables.

Les algos de cette dll sont du ressort du secret industriel.
On fait une sorte de prototype du programme dans son ensemble (ohm minimaliste, fonctionnalités minimales), mais une version "améliorée" sera peut être sous traitée ultérieurement.
On décrira juste au titulaire les entrées et sorties de la dll.
Commenter la réponse de Whismeril
NHenry 14003 Messages postés vendredi 14 mars 2003Date d'inscriptionModérateurStatut 13 décembre 2017 Dernière intervention - Modifié par NHenry le 12/11/2015 à 19:38
0
Utile
Tu peux normalement jouer sur la visibilité du constructeur d'instance (usuellement Public, Private, Internal, Protected)
Dans ton cas, un Protected serait peut être utilisable.

Après, les membres statiques ne peuvent être affectés par l'héritage (éventuellement masqué, mais uniquement si l'appel est fait par une classe enfant)

J'interviens principalement en VB6 et VB.NET, avec un peu de C#, mais la modération m'amène souvent sur d'autre langages.
En VB.NET pensez à activer "Option Explicit" et "Option Strict"
Commenter la réponse de NHenry
KX 15089 Messages postés samedi 31 mai 2008Date d'inscriptionModérateurStatut 14 décembre 2017 Dernière intervention - 12 nov. 2015 à 20:05
0
Utile
Bonsoir,

En Java on peut déclarer une classe dans une autre auquel cas elle possède tous son contenu, même privé, je ne sais pas si l'équivalent existe en C#

public final class Test {

    private Test() {
    }

    public static class SeuleClasseOuOnPeutInitialiserTest {

         private static final List<Test> tests = new List<Test>();

         static {
             tests.add(new Test());
             // ...
         }
    }
}
Commenter la réponse de KX
Whismeril 10530 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 14 décembre 2017 Dernière intervention - 12 nov. 2015 à 23:19
0
Utile
Bonsoir à tous les deux,

concernant le constructeur masqué, j'ai essayé, mais comme la classe statique ne peut pas dériver d'une classe instanciable ça ne convient pas à mon besoin.

pour la classe incorporée, ça existe (bien que le mot clé static n'ait pas le même sens dans les 2 langages), et j'ai essayé dans l'autre sens (Test dans SeuleClasseOuOnPeutInitialiserTest), je n'ai pas penser à inverser pour voir ce que cela donne.

Je tente ça demain.
Commenter la réponse de Whismeril

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.