Retourner un type pour l'utiliser comme type et non comme variable

Résolu
l0r3nz1 Messages postés 218 Date d'inscription mercredi 20 février 2008 Statut Membre Dernière intervention 17 mars 2012 - 21 déc. 2010 à 09:31
l0r3nz1 Messages postés 218 Date d'inscription mercredi 20 février 2008 Statut Membre Dernière intervention 17 mars 2012 - 23 déc. 2010 à 09:52
Bonjour,

apparement il est impossible de retourner un Type que l'on pourra utiliser comme type sans obtenir l'erreur "...variable, attendu type"

namespace autoform_transfert.serialization
{
    internal  abstract class typeCorrespondance
    {

        /// <summary>
        /// dictionnary for correspondance between serializable objets type and control type
        /// </summary>
        private  static Dictionary<Type, Type> typeCorrespondanceDictionnary = new Dictionary<Type, Type>();

        /// <summary>
        /// full dictionnary and return correspondant type
        /// </summary>
        /// control type to get correspondant serializable object


        /// <returns>type of serializable object</returns>
        public  static Type getTypeCorrespondance(Type controlType){
            typeCorrespondance.typeCorrespondanceDictionnary.Add(typeof(TextBox), typeof(serializable_text));
            typeCorrespondance.typeCorrespondanceDictionnary.Add(typeof(RichTextBox ), typeof(serializable_text ));
            typeCorrespondance.typeCorrespondanceDictionnary.Add(typeof(ComboBox ), typeof(serializable_liste ));
            typeCorrespondance.typeCorrespondanceDictionnary.Add(typeof(ListBox ), typeof(serializable_liste ));
            typeCorrespondance.typeCorrespondanceDictionnary.Add(typeof(CheckBox ), typeof(serializable_check ));
            typeCorrespondance.typeCorrespondanceDictionnary.Add(typeof(CheckedListBox ), typeof(serializable_checkListe ));
            //and ...
            return typeCorrespondanceDictionnary[controlType];
        }//end of getTypeCorrespondance

        /// <summary>
        /// return serializable class who correspond to this control
        /// </summary>
        /// returned class must correspond to this control


        /// <returns>a Type that correspond to serializable class who can get data from control</returns>
        public static Type getTypeCorrespondance(Control c) {
            return getTypeCorrespondance(c.GetType());
        }//end of getTypeCorrespondance

    }//end of classe typeCorrespondance
}//end of namespace serialization


j aimerais savoir s il existe une possiblité de lier ce genre de fonction a un typage dynamique<T> ou a une fonction qui pourrais retourner des objets de type different...

merci d avance.

2 réponses

cs_Robert33 Messages postés 834 Date d'inscription samedi 15 novembre 2008 Statut Membre Dernière intervention 14 janvier 2017 33
22 déc. 2010 à 18:35
Bonsoir

Difficile de répondre sans avoir plus de détail de ce que tu veux faire.
mais en lisant le code, je crois deviner ;-)

Je suppose que les classe de sérailisation possedent une interface commune (Serialize, Deserialize).
et un constructeur attendant le control en référence.

voila un peu de code:
    // l'interface commune
    internal interface Iserializable
    {
        string Serialize();
        Control Deserialize();
    }
    // un exemple pour un type de control, les autres sont calqués dessus
    internal class serializable_text : Iserializable
    {
        public serializable_text(TextBox t) { }
        public serializable_text(RichTextBox t) { }

        #region Iserializable Members
        public string Serialize() { throw new NotImplementedException(); }
        public Control Deserialize() { throw new NotImplementedException(); }
        #endregion
    }
 

//ta classe static, je l'ai un peu modifiée pour mettre le remplissage du tableau dans le constructeur static, c'est plus propre.
    internal abstract class typeCorrespondance
    {

        /// <summary>
        /// Static contructor, fill static dictionnary
        /// </summary>
        static typeCorrespondance()
        {
            typeCorrespondance.typeCorrespondanceDictionnary.Add(typeof(TextBox), typeof(serializable_text));
            typeCorrespondance.typeCorrespondanceDictionnary.Add(typeof(RichTextBox), typeof(serializable_text));
            typeCorrespondance.typeCorrespondanceDictionnary.Add(typeof(ComboBox), typeof(serializable_liste));
            typeCorrespondance.typeCorrespondanceDictionnary.Add(typeof(ListBox), typeof(serializable_liste));
            typeCorrespondance.typeCorrespondanceDictionnary.Add(typeof(CheckBox), typeof(serializable_check));
            typeCorrespondance.typeCorrespondanceDictionnary.Add(typeof(CheckedListBox), typeof(serializable_checkListe));
        }

        /// <summary>
        /// dictionnary for correspondance between serializable objets type and control type
        /// </summary>
        private static Dictionary<Type, Type> typeCorrespondanceDictionnary = new Dictionary<Type, Type>();

        /// <summary>
        /// return correspondant type
        /// </summary>
        /// control type to get correspondant serializable object


        /// <returns>type of serializable object</returns>
        public static Type getTypeCorrespondance(Type controlType)
        {
            return typeCorrespondanceDictionnary[controlType];
        }

        /// <summary>
        /// return serializable class who correspond to this control
        /// </summary>
        /// returned class must correspond to this control


        /// <returns>a Type that correspond to serializable class who can get data from control</returns>
        public static Type getTypeCorrespondance(Control c)
        {
            return getTypeCorrespondance(c.GetType());
        }
    }


// enfin un exemple d'utilisation
// l'idée est de créer à la volée un objet sur le type retourné par ta classe de correspondance.
// puis de l'utilisé en appelant les méthodes de l'interface commune.
public class typeCorrespondanceUsage
    {
        //just a simple test
        public void use()
        {
            //simulate a control
            ComboBox c = new ComboBox();
            // suppose that all serialisator class have a constructor with a Control type's parameter.
            // get the consturctor reference and instanciate an object
            Iserializable SerialisableObject = typeCorrespondance.getTypeCorrespondance(c).GetConstructor(new Type[] { c.GetType() }).Invoke(new object[] { c }) as Iserializable;
            //use of the common interface.
            string buffer = SerialisableObject.Serialize();
            
        }
    }
}



Bon code
Bob.
C# is amazing, enjoy it!
3
l0r3nz1 Messages postés 218 Date d'inscription mercredi 20 février 2008 Statut Membre Dernière intervention 17 mars 2012
23 déc. 2010 à 09:52
Bonjour Robert33,

merci une fois de plus pour ton aide.

je retiens surtout cette ligne, a "assimiler":
Iserializable SerialisableObject = typeCorrespondance.getTypeCorrespondance(c).GetConstructor(new Type[] { c.GetType() }).Invoke(new object[] { c }) as Iserializable;


Expliquer ce que je voulais faire était un peu long, j'ai été un peu paresseux.
Mais tu as deviné. Je veux recolter des données des controles d'un formulaire dans des objets (sérializables_XXX) que je stocke dans un tableau et/ou une liste d'objet commun (serializable_comon) pour pouvoir remplir un autre formulaire en faisant correspondre les noms de controles (ComboBox "Nom" rempli le TextBox "Nom") ou le même après l'avoir sérializé.

l'extension sera d'avoir ce dynamisme avec une BDD sqlServeur, mysql ou même access (BDD->Form, Form->BDD )en faisant correspondre les noms de champ et noms de controles

le défi (réussi dans la classe "serializable_common" sans "s") est d'utiliser un tableau ou une liste de delegate.

pour plus de précision:
http://www.csharpfr.com/codes/TRANSFERT-DONNEES-SERIALIZATION-XML-WINFORM_52629.aspx

Bon code
Daniel.
0
Rejoignez-nous