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 :

Problème de conversion d'une liste d'interface à son classe originale


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre du Club
    Inscrit en
    Février 2010
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Février 2010
    Messages : 7
    Par défaut Problème de conversion d'une liste d'interface à son classe originale
    Bonjour
    Je me suis bloqué au niveaux d'une conversion d'une liste d'interface à son propre classe.

    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
     
    /*Interface IField*/
    public interface IField
        {
            string FieldName { get; set; }
            string FieldType { get; set; } 
     
        }
     
    /*Son implémentation*/
    public class Field : IField
        {
                 public Field(string fieldName, string fieldType)
                 {
                    this.FieldName = fieldName;
                    this._fieldType = fieldType;
                 }
     
                 public string FieldName {   get ;   set;  }
                 public string FieldType{   get ;   set;  }
      }
    La 2ème interface qui parmi de ces attributs un de type IField.

    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
     
    public interface IProtocol
        {
            string NameProtocol { get; set; }
            string Id { get; set; }
            List<IField> FieldList { get; set; }
        }
    /*Son implémentation*/
     
    public class Protocol : IProtocol
        {
     
          public Protocol(string nameProtocol, string id, List<IField> fieldList)
            {
                this.NameProtocol = nameProtocol;
                this.Id = id;
                this.FieldList = fieldList;
            }
     
             public string NameProtocol{   get ;   set;  }
             public string Id{   get ;   set;  }
             public List<IField> FieldList{   get ;   set;  }
      }
    Ce que je veux c'est convertir la liste de IField en liste de Field pour avoir un constructeur où FieldList est de type List<Field> comme:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
     public Protocol(string nameProtocol, string id, List<Field> fieldList)
            {
                this.NameProtocol = nameProtocol;
                this.Id = id;
                this.FieldList = fieldList;
            }
    
     public List<Field> FieldList{   get ;   set;  }
    Le problème si j'utilise le 2eme constructeur j'aurais un problème d'implémentation car son Interface possède une liste de IField.
    Celle la sa marche: IField Ifield = new Field();
    Mais celle ci non: List<IField> fields = new List<Field>(); "Err convertion"
    Avez vous de solution?

    Merci
    Cordialement

  2. #2
    Membre Expert Avatar de meziantou
    Homme Profil pro
    autre
    Inscrit en
    Avril 2010
    Messages
    1 223
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : autre
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2010
    Messages : 1 223
    Par défaut
    Ca s'appelle la covariance.
    En c# 4 il y a 2 mot clés pour les génériques in et out.

  3. #3
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Il n'y a aucune relation d'héritage entre List<Field> et List<IField>, l'affectation que tu cherches à faire n'est donc pas possible. Si c'était possible, ça permettrait de faire des choses comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    class Field : IField { ... }
    class Field2 : IField { ... }
     
    List<Field> fields = new List<Field>();
    List<IField> ifields = fields; // interdit, mais supposons que ce soit possible
    ifields.Add(new Field2()); // oops, on ajoute un Field2 à une liste de Field... BOOM !
    Une solution est d'utiliser ToList (mais ça crée une nouvelle liste) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    this.FieldList = fieldList.ToList<IField>();
    Citation Envoyé par meziantou Voir le message
    Ca s'appelle la covariance.
    Sauf qu'ici la covariance ne s'applique pas, car seules les interfaces et délégués peuvent être covariants (ou contravariants), et List<T> est une classe. Et de toutes façons, même l'interface IList<T> n'est pas covariante (ni contravariante) en T, car T apparait aussi bien en sortie qu'en entrée.

  4. #4
    Membre du Club
    Inscrit en
    Février 2010
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Février 2010
    Messages : 7
    Par défaut
    Citation Envoyé par tomlev Voir le message
    Il n'y a aucune relation d'héritage entre List<Field> et List<IField>, l'affectation que tu cherches à faire n'est donc pas possible. Si c'était possible, ça permettrait de faire des choses comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    class Field : IField { ... }
    class Field2 : IField { ... }
     
    List<Field> fields = new List<Field>();
    List<IField> ifields = fields; // interdit, mais supposons que ce soit possible
    ifields.Add(new Field2()); // oops, on ajoute un Field2 à une liste de Field... BOOM !
    Une solution est d'utiliser ToList (mais ça crée une nouvelle liste) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    this.FieldList = fieldList.ToList<IField>();


    Sauf qu'ici la covariance ne s'applique pas, car seules les interfaces et délégués peuvent être covariants (ou contravariants), et List<T> est une classe. Et de toutes façons, même l'interface IList<T> n'est pas covariante (ni contravariante) en T, car T apparait aussi bien en sortie qu'en entrée.
    Merci pour votre réponse mais this.FieldList = fieldList.ToList<IField>(); vas convertir list<IField> en list<Field> mais j'aurais une erreur de convertion d'une list vers classe, sachant que Field implémente IField aussi j'ai pas compris la covariance, pouvez vous me donner un exemple bien préçi svp !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     public Protocol(string nameProtocol, string id, List<Field> fieldList, )
            {
            //lp = _fieldList.ConvertAll(new Converter<IField, Field>(IFieldToField));
                            
                this.NameProtocol = nameProtocol;
                this.LongName = longName;
                this.Id = id;
                this.FieldList = fieldList.ToList<Field>(); //Err convertion
                this.Encapsulation = encapsulation;
    
               
    
            }

  5. #5
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Citation Envoyé par khalifanizar Voir le message
    Merci pour votre réponse mais this.FieldList = fieldList.ToList<IField>(); vas convertir list<IField> en list<Field>
    Non, ça va convertir List<Field> en List<IField>... dans ton code tu as écrit .ToList<Field>() au lieu de .ToList<IField>()
    Citation Envoyé par khalifanizar Voir le message
    aussi j'ai pas compris la covariance, pouvez vous me donner un exemple bien préçi svp !
    Par exemple, IEnumerable<T> est covariant en T, c'est à dire que si Y hérite de X, alors un IEnumerable<Y> peut être affecté à un IEnumerable<X>.

    Exemple avec X = object et Y = string :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    List<string> listOfStrings = new List<string>(); // List<T> implémente IEnumerable<T>
    IEnumerable<object> objects = listOfStrings;
    (une séquence de strings peut être considérée comme une séquence d'objects)

    La contravariance, c'est le contraire. Par exemple, Action<T> est contravariant en T, c'est à dire que si Y hérite de X, alors un Action<X> peut être affecté à un Action<Y> :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Action<object> actionOnObject = o => Console.WriteLine(o.ToString());
    Action<string> actionOnString = actionOnObject;
    actionOnString("Hello");
    (une action qui s'applique à n'importe quel object peut être appliquée à une string, puisqu'une string est un object)

    Pour plus de détails, regarde cet article

  6. #6
    Membre du Club
    Inscrit en
    Février 2010
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Février 2010
    Messages : 7
    Par défaut
    Citation Envoyé par tomlev Voir le message
    Non, ça va convertir List<Field> en List<IField>... dans ton code tu as écrit .ToList<Field>() au lieu de .ToList<IField>()

    Par exemple, IEnumerable<T> est covariant en T, c'est à dire que si Y hérite de X, alors un IEnumerable<Y> peut être affecté à un IEnumerable<X>.

    Exemple avec X = object et Y = string :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    List<string> listOfStrings = new List<string>(); // List<T> implémente IEnumerable<T>
    IEnumerable<object> objects = listOfStrings;
    (une séquence de strings peut être considérée comme une séquence d'objects)

    La contravariance, c'est le contraire. Par exemple, Action<T> est contravariant en T, c'est à dire que si Y hérite de X, alors un Action<X> peut être affecté à un Action<Y> :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Action<object> actionOnObject = o => Console.WriteLine(o.ToString());
    Action<string> actionOnString = actionOnObject;
    actionOnString("Hello");
    (une action qui s'applique à n'importe quel object peut être appliquée à une string, puisqu'une string est un object)

    Pour plus de détails, regarde cet article
    Merci encore une fois je sais que j'ai mis .ToList<Field>() au lieu de .ToList<IField>() car je veux avoir dans la classe de protocol un attribut List<Field> et non pas List<IField> pour pouvoir sérialiser une liste de protocole y compris une liste de Field de type Field, j'espr que vous m'avez compris bien maintenant!

Discussions similaires

  1. [CSS] Problème d'espaces dans une liste
    Par sylsau dans le forum Mise en page CSS
    Réponses: 3
    Dernier message: 03/08/2006, 13h46
  2. Problème sur évènement d'une liste déroulante
    Par krfa1 dans le forum Access
    Réponses: 7
    Dernier message: 05/05/2006, 08h03
  3. Réponses: 17
    Dernier message: 03/05/2006, 14h01
  4. [vbnet] problème de conversion dans une datagrid
    Par Jsh dans le forum Windows Forms
    Réponses: 5
    Dernier message: 04/09/2005, 12h40
  5. Réponses: 4
    Dernier message: 16/06/2005, 15h37

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