Hashtable de collections, pb de conception ?

Hashtable de collections, pb de conception ? - C#/.NET managed - Programmation

Marsh Posté le 10-03-2008 à 14:51:28    

Bonjour à tous :hello:,
 
j'ai un petit soucis de conception, ma solution ne me semble pas très "fine" :( .
 
Je bosse avec le sdk d'un appareil photo, j'ai wrappé les appels aux méthodes du
sdk dans différentes classes.  
 
J'ai donc une classe "Camera", avec différentes propriétés et méthodes retournant les réglages
possibles, genre :

  • camera.GetShootingModes()
  • camera.GetISOSpeeds()  

sous forme de  

Code :
  1. Dictionary<K,V>


Pour camera.GetISOSpeeds() (par exemple) les couples (clef, valeur) sont du genre ("ISO 400",
0x48), avec valeur = la valeur à passer à Camera.ISO (propriété) pour régler
l'appareil en ISO 400.
 
Et j'ai quelques combobox dans une IHM, remplies automatiquement avec les clefs
de ces collections, pour avoir par exemple une liste contenant "ISO 80", "ISO
200", etc etc.  
Quasiment toutes les fonctions de l'appareil sont "mappables" sur
des combobox, car c'est quasiment toujours un réglage à sélectionner parmi une liste de
possibilités fournie par l'appareil.
 
 
Il s'avère que toutes mes combobox ont le même comportement, quand je click sur
"ISO 400" je veux :

  • chopper 0x48 dans la collection contenant les couples pour l'ISO
  • faire Camera.PROPRIETE = cette valeur (0x48), donc Camera.ISO=0x48; ici


Pour éviter d'implémenter autant de méthodes écoutant les évènements qu'il y a
de comboboxes
, j'aurai bien tout cablé sur la même méthode, qui aurait utilisé  
l'émetteur de l'évènement (donc la combobox) comme clef donnant accès, dans une
hashtable, à une struct "Triplet"
contenant :

  • la collection à utiliser pour trouver 0x48 (ou un delegate vers Camera.GetISOSpeeds() mais bon autant stocker tout ca...)
  • le delegate vers Camera.ISO pour pouvoir faire le Camera.ISO = 0x48 (avec un peu de réflexivité)
  • la combobox elle-même (ca peut servir, ou pas, faut voir)


Problème :
si je stock mon "Triplet", il me faut stocker en fait un  

Code :
  1. Triplet<K,V>


car l'une des données membre de la struct est un  

Code :
  1. Dictionary<K,V>


car à l'origine, GetISOSpeeds() me retourne un  

Code :
  1. Dictionary<string, struct_contenant_les_ISO_kisontdes_bytes>


 
Donc ma collection de Triplet<K,V> (avec pleins de K et V différents) est une
Hashtable (key=Combobox, value=Object)  
mais le drame c'est que je ne peux pas sortir un Triplet directement,
ne connaissant pas les types K et V. Un coup c'est :

Code :
  1. Dictionary<string, int>


une autre fois ça sera  

Code :
  1. Dictionary<string, byte>


ou  

Code :
  1. Dictionary<int, type_a_la_kon>


 
 
 
Je pense pouvoir m'en sortir avec du typeof(instance) ou autre, mais bon :/
J'aurai bien aimé au moins un truc à la C++ genre :

Code :
  1. if (TypeA a = dynamic_cast<TypeA>(..)) { }
  2. else if (TypeB b = dynamic_cast<TypeB>(..)) { }
  3. ...


 
Si quelqu'un a une idée sur comment stocker cette association "combobox/collection
générique/property à appeler", je suis preneur :jap:


Message édité par Xavier_OM le 11-03-2008 à 10:10:54

---------------
Il y a autant d'atomes d'oxygène dans une molécule d'eau que d'étoiles dans le système solaire.
Reply

Marsh Posté le 10-03-2008 à 14:51:28   

Reply

Marsh Posté le 10-03-2008 à 14:58:44    

Reply

Marsh Posté le 10-03-2008 à 15:00:14    


 
Triplet en est une justement :o  
 

private struct Triplet<K,V> {
 public ComboBox cbx;
 public Dictionary<K, V> dico;
 public MySetDelegate deleg;
}



---------------
Il y a autant d'atomes d'oxygène dans une molécule d'eau que d'étoiles dans le système solaire.
Reply

Marsh Posté le 10-03-2008 à 15:06:32    

ah merde [:petrus75]
sinon tu as le mot clé "is" qui se rapproche un peu de l'usage du dynamic_cast : http://msdn2.microsoft.com/en-us/l [...] S.80).aspx

Reply

Marsh Posté le 10-03-2008 à 15:41:39    

Harkonnen a écrit :

ah merde [:petrus75]
sinon tu as le mot clé "is" qui se rapproche un peu de l'usage du dynamic_cast : http://msdn2.microsoft.com/en-us/l [...] S.80).aspx

 

mmm donc ca ferait un truc genre :

 
Code :
  1. ComboBox cbx   = (ComboBox)sender;
  2. string setting = cbx.SelectedItem as string;
  3. Object collec  = this.associationsTable[cbx]; // Hashtable de Triplet
  4. if (collec is Triplet<string, ushort> ) {
  5.     Triplet<string, ushort> t = (Triplet<string, ushort> )collec;
  6.     this.SetSetting(t, setting);
  7. }
  8. else if (collec is Triplet<string, prType.prptpMetering> ) {
  9.     Triplet<string, prType.prptpMetering> t = (Triplet<string, prType.prptpMetering> )collec;
  10.     this.SetSetting(t, setting);
  11. }
  12. else if (collec is Triplet<string, uint> ) {
  13.     Triplet<string, uint> t = (Triplet<string, uint> )collec;
  14.     this.SetSetting(t, setting);
  15. }
  16. else if (collec is Triplet<string, prType.prptpImageQuality> ) {
  17.     Triplet<string, prType.prptpImageQuality> t = (Triplet<string, prType.prptpImageQuality> )collec;
  18.     this.SetSetting(t, setting);
  19. }
  20. void SetSetting<K,V>(Triplet<K,V> t, string setting) { ... }
 


Du coup j'ai toutes mes comboboxes sur le même gestionnaire d'events, mais je dois encore augmenter le code à chaque nouveau type de collection générique que me renvoie le sdk.
Bon c'est déjà pas mal... mais jpeux pas m'empêcher de trouver ce bout de code inélégant :/

 


edit :
en fait si mon écouteur d'évènement peut être un

Code :
  1. private void comboBox_SelectedIndexChanged<K,V>(object sender, EventArgs e)


au lieu d'un

Code :
  1. private void comboBox_SelectedIndexChanged(object sender, EventArgs e)


alors j'ai gagné :o


Message édité par Xavier_OM le 10-03-2008 à 15:46:05

---------------
Il y a autant d'atomes d'oxygène dans une molécule d'eau que d'étoiles dans le système solaire.
Reply

Marsh Posté le 10-03-2008 à 15:46:08    

et un Factory, ça ne pourrait pas t'aider ?

Reply

Marsh Posté le 10-03-2008 à 16:29:44    

Bon ca marche avec du :

Code :
  1. private void comboBox_SelectedIndexChanged<K,V>(object sender, EventArgs e)


 
et du :

Code :
  1. this.comboBoxSearchRange.SelectedIndexChanged +=
  2.         new System.EventHandler(this.comboBox_SelectedIndexChanged<string, byte> );


 
Mais très bonne idée le Factory, j'y avais pas du tout pensé... je vais voir si ca peut donner un truc plus propre :)


---------------
Il y a autant d'atomes d'oxygène dans une molécule d'eau que d'étoiles dans le système solaire.
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed