2010-07-01 3 views
3

J'aimerais pouvoir créer un tableau associatif multidim dont une dimension est une classe. Comme ceci:Tableau associatif où une classe TypeInfo est la clé dans D?

class Node{ 
    Node[?classType?][string] inputs; 
} 

pour que je puisse faire plus tard

Node[] getInputsOfType(?? aClass){ 
    if(aClass in this.inputs) 
     return this.inputs[aClass]; 
    else 
     return null; 
} 

// meanwhile in another file... 

Node[] effects = someAudioNode.getInputsOfType(AudioEffect); 

Je viens de perdre. Des idées?
Concernant la dernière partie: Une classe peut-elle être utilisée comme paramètre tout seul comme ça? (AudioEffect dans cet exemple est une classe.)

BR

[mise à jour/résolution]

Merci pour la réponse (s)!

Je pensais que ce serait bien d'afficher le résultat. Ok, j'ai recherché .classinfo dans le code source et trouvé qu'il renvoie une instance de TypeInfo_Class, et qu'il y a un .name -property, un string. Voilà donc ce que je suis venu avec:

#!/usr/bin/env dmd -run 
import std.stdio; 
class A{ 
    int id; 
    static int newId; 
    A[string][string] list; 
    this(){ id = newId++; } 
    void add(A a, string name){ 
     writefln("Adding: [%s][%s]", a.classinfo.name, name); 
     list[a.classinfo.name][name] = a; 
    } 
    T[string] getAllOf(T)(){ 
     return cast(T[string]) list[T.classinfo.name]; 
    } 
} 
class B : A{ } 
void main(){ 
    auto a = new A(); 
    a.add(new A(), "test"); 
    a.add(new B(), "bclass"); 
    a.add(new B(), "bclass2"); 

    auto myAList = a.getAllOf!(A); 
    foreach(key, item; myAList) 
     writefln("k: %s, i: %s id: %s", 
       key, item.toString(), item.id); 

    auto myBList = a.getAllOf!(B); 
    foreach(key, item; myBList) 
     writefln("k: %s, i: %s id: %s", 
       key, item.toString(), item.id); 
} 

Il produit:

Adding: [classtype.A][test] 
Adding: [classtype.B][bclass] 
Adding: [classtype.B][bclass2] 
Trying to get [classtype.A] 
k: test, i: classtype.A id: 1 
Trying to get [classtype.B] 
k: bclass2, i: classtype.B id: 3 
k: bclass, i: classtype.B id: 2 

Alors oui, je suppose que cela fonctionne. Yey! Quelqu'un a des idées d'amélioration?

Y a-t-il des pièges ici?

  • Est-ce que classinfo.name peut soudainement se comporter de manière inattendue?
  • Existe-t-il un moyen «approprié» d'obtenir le nom de la classe?

Aussi, est-ce le moyen le plus rapide de le faire? Je veux dire, tous les noms de classe semble commencer par classtype.. Eh bien, c'est peut-être un autre SO-thread. Merci encore!

BR

Répondre

3

Vous pouvez utiliser le faire référence à des types de classe à l'exécution classe ClassInfo (accessible via la propriété .classinfo). Cependant, la classe ClassInfo n'implémente pas les méthodes nécessaires à utiliser dans un tableau associatif (voir le D reference page on AAs concernant l'utilisation de classes/structs dans les AA). Je suppose que c'est possible si vous implémentez votre propre wrapper pour ClassInfo qui peut être utilisé comme une clé AA. Cela devrait être assez simple, car vous pouvez vous attendre à ce qu'un type de classe n'ait qu'une seule instance ClassInfo, vous pouvez donc simplement utiliser l'adresse ClassInfo comme hash unique.


Par ailleurs, une plus simple et plus rapide d'écrire

if (key in aa) 
    return aa[key]; 
else 
    return null; 

est

auto pvalue = key in aa; 
return pvalue ? *pvalue : null; 
+0

Re chaque classe ayant seulement un ClassInfo: IIRC qui pourrait ne pas être vrai si vous utilisez DLL ou SO Mais dans ces cas, vous vous retrouvez avec d'autres problèmes. – BCS

+0

Merci! J'ai fini par utiliser le '.name'-property dans classinfo, qui est juste une chaîne de caractères, ce qui ne posait pas de problème lors de l'utilisation d'un tableau associatif, bien que cela puisse paraître plus rapide./BR – 0scar

Questions connexes