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 confirmé
    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
    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 confirmé
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    92
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2006
    Messages : 92
    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 confirmé
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    92
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2006
    Messages : 92
    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 confirmé
    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
    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 : 38
    Localisation : France, Paris (Île de France)

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

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

  6. #6
    Membre confirmé
    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
    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 éprouvé Avatar de LeCygne
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2010
    Messages
    91
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Juin 2010
    Messages : 91
    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 chevronné Avatar de Jerede
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mai 2010
    Messages
    271
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Mai 2010
    Messages : 271
    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 chevronné
    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
    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