Dictionnary<T1,T2>

Résolu
ricklekebekoi Messages postés 303 Date d'inscription mardi 11 février 2003 Statut Membre Dernière intervention 24 avril 2009 - 1 août 2007 à 23:32
ricklekebekoi Messages postés 303 Date d'inscription mardi 11 février 2003 Statut Membre Dernière intervention 24 avril 2009 - 3 août 2007 à 20:47
Bonjour,

Je vais simplifier ma question.

J'ai un Dictionnary MonDico

Dans ce dictionnary, j'ai ceci:

255, "Bonjour"
544, "Allo"
1234, "Salut"

Je peut donc faire MonDico[544] et sa me retourne "Allo"

Hors, si je fait MonDico[333], sa crash !

Je doit donc faire, avant chaque utilisation, ceci:

if( MonDico.ContainsKey(333) )
    return MonDico[333];

Et j'aimerais faire autrement.
Je voudrais un truc comme le GetSet, ou je ferais le test une seule fois, mais qu'il se ferait a chaque fois.

Je sais agir sur le MonDico, exemple faire un test si il est null quand on le demande. Je peux donc agir sur le GET de l'objet MonDico, mais moi je voudrais agir sur le GET d'un élément de Mondico ... vous me suivez ? Une solution a me proposer ?

Merci

Eric

12 réponses

cs_Bidou Messages postés 5487 Date d'inscription dimanche 4 août 2002 Statut Membre Dernière intervention 20 juin 2013 61
2 août 2007 à 09:48
Salut,
Pas sûr non plus d'avoir compris la question... peut-être ceci (?) :

public
class
MyDictionary<T, U> :
Dictionary<T, U>
{
  
public
new U
this[T value]
   {
     
get
      {
        
return
this.ContainsKey(value) ?
this[value] :
default(U);
      }
   }
}

<hr />
-Blog-
3
cs_Bidou Messages postés 5487 Date d'inscription dimanche 4 août 2002 Statut Membre Dernière intervention 20 juin 2013 61
2 août 2007 à 15:48
Le new n'est pas obligatoire mais conseilé, car tu "surécrit" un membre de la class de base. Avec new, tu indiques clairement que c'est un comportement voulu.

Concernant ton problème, le plus simple reste peut-être de définir une interface (voire une class abstraite) qui sera implémentée par Maison et Chien. Dans la déclaration de ta class Dictionnary, tu spécifie que le type U doit implémenter cette interface grâce à la clause where.

Ensuite, il te suffira d'appeler la valeur de l'interface que tu souhaites récupérer (retourner), je sais pas si c'est clair?

<hr />
-Blog-
3
ricklekebekoi Messages postés 303 Date d'inscription mardi 11 février 2003 Statut Membre Dernière intervention 24 avril 2009 5
2 août 2007 à 15:53
Et pour ceux qui liront ce post, un exemple plus concret

class Dictionary<TKey,TVal>
where TKey: IComparable, IEnumerable
where TVal: MyI
{
public void Add(TKey key, TVal val)
{
}
}
3
Lutinore Messages postés 3246 Date d'inscription lundi 25 avril 2005 Statut Membre Dernière intervention 27 octobre 2012 41
2 août 2007 à 00:39
Salut, pas trop compris la question.. mais la classe Dictionary à une méthode TryGetValue rapide et pratique.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
ricklekebekoi Messages postés 303 Date d'inscription mardi 11 février 2003 Statut Membre Dernière intervention 24 avril 2009 5
2 août 2007 à 00:58
Bon, j'ai fait quelque petites recherches pour le TryGetValue
C'est intéressant, mais c'est pas encore ce que je recherche.

En fait, si la Key n'existe pas, j'aimerais le gerer moi meme.

un peu du style comme sa

private Dictionnary _MonDico = new Dictionnary();
public Dictionnary MonDico
{
   get{ return _MonDico; }
   set{ _MonDico = value; }
}
public Dictionnary MonDico[index]
{
   get
   { 
      if( MonDico.ContainsKey(index)) 
         return MonDico[index]; 
      else 
         return "Inconnu";
   }
   set
   {       
      if( MonDico.ContainsKey(index)) 
         MonDico[index] = value;  
   }
}

Je me doute que ce type de programmation ne fonctionne pas, mais sa illustre bien et clairement ce que je recherche

Eric
0
PurBonheur Messages postés 66 Date d'inscription samedi 24 février 2007 Statut Membre Dernière intervention 7 octobre 2007 1
2 août 2007 à 07:29
Salut, tu peux peut être utiliser un bloc try catch

public partial class Form1 : Form
    {
        System.Collections.Generic.Dictionary dico = new Dictionary();

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            dico.Add(533, "Hello");
            dico.Add(1234, "Bonjour");
            try
            {
                string chaine = dico[333];
            }
            catch (Exception ex)
            {
                MessageBox.Show("Erreur.");
            }
        }
    }

A plus.
0
ricklekebekoi Messages postés 303 Date d'inscription mardi 11 février 2003 Statut Membre Dernière intervention 24 avril 2009 5
2 août 2007 à 14:46
Je croit que Bidou à ce que compris ce que je veux.


Est-ce que ce que tu me donne retournera ceci ?




MyDictionary MonDico = new MyDictionary();
MonDico.Add(111,"A");
MonDico.Add(222,"B");



MonDico.Add(333,"C");
string string1 = MonDico[222]; // string1 aura "A" comme valeur;
string string1 = MonDico[444]; // string1 aura null comme valeur;



????

Si c'est bon, c'est donc ce que je recherche.

Autre chose, si au lieu de string, j'ai MyDictionary MonDico. Y-a-til un moyen de définir le "default value" de ma propre classe ?? En fait définir la valeur retournée dans default(U);

Merci pour tout

Eric
0
cs_Bidou Messages postés 5487 Date d'inscription dimanche 4 août 2002 Statut Membre Dernière intervention 20 juin 2013 61
2 août 2007 à 14:58
Oui, si tu prends l'exemple que je t'ai donné, alors tu auras le comportement que tu souhaites.
Pour le dictionnaire, ça ne change rien la façon dont tu l'initialises (avec un string ou MaClasse) étant donné qu'il est Généric... Tout ce que tu dois faire, c'est retourne un type "U"

<hr />
-Blog-
0
ricklekebekoi Messages postés 303 Date d'inscription mardi 11 février 2003 Statut Membre Dernière intervention 24 avril 2009 5
2 août 2007 à 15:35
En fait, ce que je veux dire, c'est que imaginons 2 classes, Chien et Maisons

Dans mon code, j'ai ceci

MyDictionary MonDico1 = new MyDictionary();
MonDico1.Add(111,new Chien("Fido",5));
MonDico1.Add(222,new Chien("Ralphy",8)););
MonDico1.Add(333,new Chien("Boxie",5)););
string string1 = MonDico1[111]; // string1 aura le chien du nom de Fido comme valeur;
string string2 = MonDico1[444]; // string1 aurait le chien new Chien("Inconnu",0); comme valeur
MyDictionary MonDico2 = new MyDictionary();
MonDico2.Add(555,new Maison("Paris","rue 1"));
MonDico2.Add(666,new Maison("Québec","rue 2")););
MonDico2.Add(777,new Maison("New Yorl","rue 3")););
string string1 = MonDico[555]; // string1 aura la maison a Paris comme valeur;
string string2 = MonDico[888]; // string1 aurait la maison new Maison("Inconnu","Inconnu"); comme valeur

Je souhaite donc définir la valeur par défaut de la classe Chien et de la classe Maison. Pour que dans la classe MonDictionnary, je puisse faire default(U); et si U est typeof(Maison), sa me retourne new Maison("Inconnu","Inconnu");, si U est typeof(Chien), sa me retourne new Chien("Inconnu",0);, et si U est un autre type, sa me retourne son default() normal.
Ya moyen de faire cela ?

Et Sinon, autres question, dans la ligne
public new U this[T value]
Est-ce que le "new" est obligatoire ? et Pourquoi ?

Merci encore

Eric
0
ricklekebekoi Messages postés 303 Date d'inscription mardi 11 février 2003 Statut Membre Dernière intervention 24 avril 2009 5
2 août 2007 à 15:51
Oui, j'avais penser a l'interface ou a la classe bastraite, je me demandais si yavais moyen autre de le faire :)

J'ai tout compris, sauf l'histoire de la clause where :)
0
ricklekebekoi Messages postés 303 Date d'inscription mardi 11 février 2003 Statut Membre Dernière intervention 24 avril 2009 5
2 août 2007 à 15:52
C'est bon, google est mon ami :)

using System;

class MyClassy<T, U>
where T : class
where U : struct
{
}
0
ricklekebekoi Messages postés 303 Date d'inscription mardi 11 février 2003 Statut Membre Dernière intervention 24 avril 2009 5
3 août 2007 à 20:47
Encore moi.

Je bloque sur la derniere partie de ma question, jai tout compris ce que l'on m'a dit de faire, le probleme étant au moment de l'exécuter.

Voila ce que jai tenter, mais encore une fois, en me doutant que ça ne fonctionnerait pas:

ICookingEntry<T>
=
public

interface
ICookingEntry<T>
{
   
static T DefaultEntry
   {
      
get;
   }
}

=

CookingDico<T,U> : Dictionnary<T,U>
=

public
class
CookingDico<TKey, TValue> :
Dictionary<TKey, TValue>
            
where TValue :
ICookingEntry<TValue>
{
   
public
new TValue
this[TKey value]
   {
      
get
      {
         
if ( ContainsKey( value ) )
            
return
base[value];
         
else
            return ( (
ICookingEntry<TValue>)TValue ).DefaultEntry;
      }
   }
}


En effet, il me semblait bien que mettre un membre static a une interface était étrange ... et que la ligne 
 return ( (ICookingEntry<TValue>)TValue ).DefaultEntry;
Était d'autant plus étrange.

Comment devrais-je faire le tout ???
Eric
0
Rejoignez-nous