2010-05-08 6 views
1

Y at-il de toute façon que je peux le faire?Classe de collecte générique?

class TSOC<TCollection, TValue> : ICollection<TValue>, INotifyCollectionChanged where TCollection : ICollection 
{ 
    private TCollection<TValue> collection; 
} 

Il n'aime pas ma définition de collection. Je préfère que la définition ressemble à TSOC<TCollection> où l'utilisateur peut passer List<int> ou quelque chose, mais j'ai besoin de sortir le "int" pour savoir quelle interface mettre en œuvre.


Fondamentalement, je voulais juste envelopper toutes les ICollection méthodes locks et les forcer à courir sur un fil particulier, mais toujours garder toutes les fonctionnalités supplémentaires de la collection de choix du programmeur .... Je ne suis pas C'est sûr que c'est possible.

Répondre

4

Que diriez-vous:

class TSOC<TCollection, TValue> : ICollection<TValue>, INotifyCollectionChanged 
    where TCollection : ICollection<TValue> 
{ 
    private TCollection collection; 
} 

Je pense que c'est ce que vous cherchez. Il semble que vous essayiez d'encapsuler une collection générique et que vous vouliez que le premier type de paramètre soit une collection existante du même type. Cela vous donnera exactement cela.

Difficile à dire, mais vous n'avez peut-être même pas besoin de cela. À moins que vous avez vraiment besoin de connaître le type sous-jacent de l'objet TCollection, vous pourriez probablement faire une TSOC<TValue> et d'accepter un ICollection<TValue> pour l'envelopper avec:

class TSOC<TValue> : ICollection<TValue>, INotifyCollectionChanged 
{ 
    private ICollection<TValue> collection; 
} 

Ceci est fonctionnellement la même chose, vous ne pourrez pas avoir une connaissance du type sous-jacent réel du ICollection<TValue>.


Mise à jour:

répondre maintenant à cette édition:

Fondamentalement, je voulais juste envelopper toutes les méthodes de ICollection dans les écluses et les forcer à courir sur un fil particulier, mais encore garder toutes les fonctionnalités supplémentaires de la collection de choix du programmeur .... Je ne suis pas sûr que ce soit possible si

Je pense que vous réellement pourrait atteindre ce que vous voulez, mais peut-être d'une manière légèrement différente que vous attendez. Vous ne même pas vraiment besoin de cette collection, vous voulez juste un wrapper synchronisé:

public class Synchronized<T> 
{ 
    private readonly object sync = new Object(); 

    private T item; 

    public Synchronized(T item) 
    { 
     this.item = item; 
    } 

    public void Execute(Action<T> action) 
    { 
     lock (sync) 
      action(item); 
    } 

    public TResult Evaluate<TResult>(Func<T, TResult> selector) 
    { 
     lock (sync) 
      return selector(item); 
    } 
} 

Utilisez ensuite comme:

var sc = new Synchronized<ICollection<int>>(new List<int>()); 
sc.Execute(c => c.Add(3)); 
int count = sc.Evaluate(c => c.Count); 

Maintenant, je sais que ce n'est pas exactement ce que vous voulez, car il ne vous donne pas réellement une instance de ICollection<T> vous pouvez passer autour. Mais c'est une encapsulation propre du comportement de verrouillage et cache la collection interne, de sorte que vous pouvez garantir que chaque opération est "thread safe".

Si vous avez réellement besoin d'une instance équivalente de ICollection<T> qui enveloppe ICollection<T> tout en ajoutant la sécurité des threads, alors vous recherchez réellement l'interception de méthode en utilisant une bibliothèque comme Castle DynamicProxy.

+0

En fait, je ne pense pas que j'aie entièrement réfléchi à cela. L'idée était qu'ils pouvaient transmettre une 'SortedList' ou' Queue' ou quoi que ce soit, s'ils avaient besoin de leur collection pour avoir certaines propriétés, mais je me suis juste rendu compte qu'ils n'auraient accès à aucune des méthodes supplémentaires de ces collections ont de toute façon ... donc l'une de vos solutions fonctionnerait probablement bien. A moins que je puisse hériter de TCollection, je pense que ma classe sera inutile: \ – mpen

+0

W/votre 2ème sol'n ... vous ne pouvez pas instancier un 'ICollection' ... cependant, je pourrais forcer le programmeur à passer une collection au c'tor je suppose, comme Matt le fait remarquer. – mpen

+0

Belle mise à jour! Cependant, je ne pense pas que je veuille me diriger vers l'une ou l'autre de ces routes pour l'instant ... Je vais juste écrire quelques collections personnalisées qui correspondent à mes besoins pour le moment :) – mpen

1

Si le consommateur de votre classe passe en isntance de la collection, il se peut que vous n'ayez pas besoin de le spécifier comme faisant partie de la définition générique de la classe.

public class TSCO<T> : ICollection<T>, INotifyCollectionChanged 
{ 
    public TSCO(ICollection<T> collection) 
    { 
     _collection = collection; 
    } 

    private ICollection<T> _collection; 
} 

Vous avez besoin d'un objet qui implémente ICollection<T> pour construire le type, mais vous n'avez pas besoin de le dire quel type cette collection est explicitement.

Cela fonctionnerait-il pour vous?

Questions connexes