2010-09-16 5 views
4

On dirait que j'ai oublié un nom de fichier ... Quelque chose dans ma tête me dit toujours que j'ai trébuché sur un dictionnaire qui utilise fondamentalement un comparateur défini par l'utilisateur pour les recherches. Mais je ne peux plus trouver cette classe dans les profondeurs de .Net plus."Dictionnaire" avec clé dans le cadre des éléments stockés?

Comme je l'ai aucune idée comment décrire ce que je cherche sans décrire une mise en œuvre possible, je vais aussi donner un exemple de ce que je wan't à faire.

Je cherche basiquement un moyen d'obtenir les résultats suivants (pseudo-code):

class CustomId 
{ 
    // [...] 
} 
class Element 
{ 
    CustomId id; 
} 
Container<CustomId, Element> myContainer = new Container(myCustomComparer) 
myContainer.Add(new Element()) // No key specified 
myElement = myContainer[new CustomId(...)]; // Retrieval with custom id 

Peut-être que ce techniquement est pas tout à fait le dictionnaire, mais j'espère que l'idée est claire. Fondamentalement, la clé fait partie de l'élément stocké.

+0

Vous pouvez le construire en utilisant Reflection mais pas sûr que ce soit ce que vous cherchez. – Aliostad

+1

Je crois que le nom général de ce concept est un index. C'est comme ajouter un index dans un SGBDR sur la propriété "id" de votre objet. – rmeador

Répondre

12

Je pense que vous cherchez KeyedCollection<TKey, TItem>. Créez une classe qui hérite de cette classe et remplacez la méthode GetKeyForItem().

+0

Wow, si vite que StackOverflow ne permet même pas de le marquer comme une réponse en ce moment. –

2

C'est en fait assez facile. il vous suffit d'hériter de KeyedCollection<TKey, TItem>:

public class ElementCollection : KeyedCollection<CustomId, Element> 
{ 
    public override CustomId GetKeyForItem(Element element) 
    { 
     return element.id; 
    } 
} 
+0

Doh! On dirait que je suis trop lent à taper. Laissant ici un exemple de code de toute façon ... –

+0

Il semble que le résultat net est que vous passez un 'Element' dans la clé d'un conteneur, et vous obtenez cet' Element' de la collection retournée. Si vous avez déjà le 'Element', quel est le point? – JohnB

+1

Parce que vous n'avez pas déjà l'élément. Vous avez seulement le CustomId. La méthode GetKeyForItem est appelée en interne pour vérifier le CustomId que vous fournissez sur les éléments de la collection ... et non l'inverse. –

0

Vous pouvez faire deux choses:

Utilisez une liste simple et utiliser LINQ pour récupérer des objets par CustomID:

var elements = myContainer.Where(e=>e.CustomID == new CustomID(...)).ToList(); 

Ou, étendre la classe générique Dictionary pour fournir une surcharge Add qui sait comment projeter la clé de la valeur donnée:

public class AutoDictionary<K,V> : Dictionary<K,V> 
{ 
    public Func<V,K> KeyGenerator { get; set; } 
    public void Add(V value) 
    { 
     Add(KeyGenerator(V),V); 
    } 
} 

... 

var myContainer = new AutoDictionary<CustomId, Element>(); 
myContainer.KeyGenerator = e=> e.id; 
myContainer.Add(myElement); 
var elementFromDictionary = myContainer[myElement.id]; //will be the same instance as myElement 
Questions connexes