IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Comment Instancier un objet d'une classe avec un autre de sa classe de base simplement.


Sujet :

C#

  1. #1
    Membre du Club
    Homme Profil pro
    Inscrit en
    Septembre 2010
    Messages
    55
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 55
    Points : 49
    Points
    49
    Par défaut Comment Instancier un objet d'une classe avec un autre de sa classe de base simplement.
    Bonjour,

    Voici un problème assez commun je pense, que je n'arrive pas à solutionner de manière simple et "élégante"

    J'ai une classe B dérivé d'une classe A.
    Je souhaites instancier un objet de classe B et l'initialiser avec les données d'un objet de classe A.
    Comment réaliser le constructeur sans passer par une copie de tous les membres de A vers B.

    par exemple


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
     
    public class A {
     
         private int _entier;
         private string _chaine;
     
         public A (int entier) {
             _entier=entier;
             _chaine = string.Empty;
         }
     
        public string Entier {
     
              get { return _entier; }
              set { _entier=value;  }
        }
     
        public string Chaine {
              get { return _chaine; }
              set { _chaine=value;  }
        }
    }
     
    public class B : A
    {
           private float _flottant;
     
           public B (A a)
           {
                // c'est ca qu'il faut simplifier 
               base.Entier=a.Entier;
               base.Chaine=a.Chaine
           }
     
        public string Flotant {
              get { return _flottant; }
              set { _flottant=value;  }
        }
    }

    merci de votre aide.

  2. #2
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    92
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2006
    Messages : 92
    Points : 83
    Points
    83
    Par défaut
    Je ne sais si c'est ce que tu veux mais en ajoutant un constructeur à A, tu pourras l'appeler dans le constructeur de B :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    public class A
    {
        public A(int entier, string chaine) // Nouveau constructeur
        {
             _entier = entier;
             _chaine = chaine;
        }
    }
    public class B : A
    {
        public B(int entier, string chaine) : base(entier, chaine)
        {
        }
    }

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    92
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2006
    Messages : 92
    Points : 83
    Points
    83
    Par défaut
    Pardon, j'oubliai, tu voulais passer un objet A au constructeur de B, cela change un toup'tipeu :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    public class B : A
    {
        public B(A a) : base(a.Entier, a.Chaine)
        {
        }
    }

  4. #4
    Membre du Club
    Homme Profil pro
    Inscrit en
    Septembre 2010
    Messages
    55
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 55
    Points : 49
    Points
    49
    Par défaut
    Bonjour et merci de ta réponse Gat

    Créer un constructeur dans la classe de base avec l'ensemble des propriétés revient a peu près à la même chose.

    Mon problème provient du fait que la classe A possède en beaucoup de propriétés (cet objet correspond à une table d'une base de donnée).

  5. #5
    Rédacteur
    Avatar de Nathanael Marchand
    Homme Profil pro
    Expert .Net So@t
    Inscrit en
    Octobre 2008
    Messages
    3 615
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Expert .Net So@t
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2008
    Messages : 3 615
    Points : 8 080
    Points
    8 080
    Par défaut
    Tu peux passer par la reflexion mais c'est bof!

  6. #6
    Membre du Club
    Homme Profil pro
    Inscrit en
    Septembre 2010
    Messages
    55
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 55
    Points : 49
    Points
    49
    Par défaut
    +1 c'est bof

    Ayant manger du C pendant longtemps, je me demandais si une copie brute
    des données était envisageable à grand coup de pointeur.
    sachant que l'instanciation d'un objet dérivé est un correspond en mémoire à
    l'objet instancier sur la classe de base suivit (ou précédé je sais plus) des infos de l'instance de l'objet dérivé.

  7. #7
    Membre habitué Avatar de LeCygne
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2010
    Messages
    91
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Juin 2010
    Messages : 91
    Points : 159
    Points
    159
    Par défaut
    Bonjour,

    Pourquoi ne pas implementer IClonable sur A ? Ainsi vous pourriez ecire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    B b = (B)a.Clone();
    Je crains cependant que la fonction "Clone()" ressemble a une instanciation d'une nouvelle instance de A suivie de la copie massive que vous trouvez peu élégante.

  8. #8
    Membre averti Avatar de Jerede
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mai 2010
    Messages
    271
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Mai 2010
    Messages : 271
    Points : 422
    Points
    422
    Par défaut
    Bonsoir,

    C'est mignon la réflection , j'ai pas trop vérifié, mais normalement ça devrait fonctionner ( fais pas attention au nom de la méthode )
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
        public static Func<T1, T2> GetM<T1, T2>() where T2 : T1
        {
            var baseType = typeof(T1);
            var derivedType = typeof(T2);
     
            var dynamicMethod = new DynamicMethod(string.Empty, derivedType, new Type[] { baseType }, baseType, true);
            var ilGenerator = dynamicMethod.GetILGenerator();
     
            ilGenerator.DeclareLocal(derivedType);
            ilGenerator.Emit(OpCodes.Newobj, derivedType.GetConstructor(Type.EmptyTypes));
            ilGenerator.Emit(OpCodes.Stloc_0);
     
            foreach (var prop in baseType.GetFields(BindingFlags.Instance | BindingFlags.Public))
            {
                ilGenerator.Emit(OpCodes.Ldloc_0);
                ilGenerator.Emit(OpCodes.Ldarg_0);
                ilGenerator.Emit(OpCodes.Ldfld, prop);
                ilGenerator.Emit(OpCodes.Stfld, prop);
            }
     
            ilGenerator.Emit(OpCodes.Ldloc_0);
     
            ilGenerator.Emit(OpCodes.Ret);
     
            return dynamicMethod.CreateDelegate(typeof(Func<T1, T2>)) as Func<T1, T2>;
        }
    A utiliser comme ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
        static void Main(string[] args)
        {
            var convert = GetM<_base, herited>();
            var baseInstance = new _base {name = "lu"};
            var heritedInstance = convert(baseInstance);
            Console.WriteLine(heritedInstance.name);
            Console.Read();
        }
    Stocke le délégué dans un coin, sinon y'a plus trop d'intérêt à faire ça.

  9. #9
    Membre confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2011
    Messages
    269
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2011
    Messages : 269
    Points : 460
    Points
    460
    Par défaut
    Bonjour,

    Si j'ai bien compris tu cherches à ne pas avoir à ecrire toi meme l'affectation des membres issu de la classe de base.

    La serialisation peut etre une solution simple, en tout ca marche en DataContract. A voir si ca marcherai avec un simple XmlSerializer (dans le cas ou tu serais limité à .Net2).

    Classe A
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
     
        [DataContract]
        class ClassBase : IExtensibleDataObject
        {
            protected string _membreBase1;
            protected int _membreBase2;
     
            protected ExtensionDataObject _extensionDataObject;
     
            public ClassBase()
            {
                _membreBase1 = string.Empty;
            }
     
            [DataMember]
            public string B1
            {
                get { return _membreBase1; }
                set { _membreBase1 = value; }
            }
     
            [DataMember]
            public int B2
            {
                get { return _membreBase2; }
                set { _membreBase2 = value; }
            }
     
            public ExtensionDataObject ExtensionData
            {
                get { return _extensionDataObject; }
                set { _extensionDataObject = value; }
            }
    Classe B
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
        [DataContract]
        class ClassDerived : ClassBase
        {
            private string _membreDerived1;
     
            public ClassDerived()
            {
                _membreDerived1 = string.Empty;
            }
     
            [DataMember]
            public string D1
            {
                get { return _membreDerived1; }
                set { _membreDerived1 = value; }
            }
    code de test
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
     
                ClassBase baseInstance = new ClassBase();
                baseInstance.B1 = "toto";
                ClassDerived derivedInstance;
     
     
     
                DataContractSerializer dcsBase = new DataContractSerializer(typeof(ClassBase));
                DataContractSerializer dcsDerived = new DataContractSerializer(typeof(ClassDerived));
                MemoryStream ms = null;
                try
                {
     
                    using (ms = new MemoryStream())
                    {
                        dcsBase.WriteObject(ms, baseInstance);
                        ms.Flush();
     
                        baseInstance.B2++;
                        ms.Seek(0, SeekOrigin.Begin);
     
                        derivedInstance = (ClassDerived)dcsDerived.ReadObject(ms);
                    }
                    ms = null;
                }
                finally 
                {
                    if (ms == null)
                        ms.Close();
                }

Discussions similaires

  1. Réponses: 2
    Dernier message: 13/04/2010, 12h45
  2. Réponses: 8
    Dernier message: 16/02/2007, 15h55
  3. Réponses: 4
    Dernier message: 08/03/2006, 19h07
  4. Réponses: 6
    Dernier message: 18/01/2006, 16h26

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo