2009-08-28 23 views
4

Exemple: Je voudrais avoir la méthode Add de ICollection d'une classe de collection personnalisée pour mettre en œuvre de méthodes enchaînées et langues couramment, donc je peux le faire:Existe-t-il un moyen simple et élégant de rendre ICollection plus fluide en C#?

randomObject.Add("I").Add("Can").Add("Chain").Add("This"). 

Je peux penser à quelques options, mais ils sont en désordre et implique d'encapsuler ICollection dans une autre interface et ainsi de suite.

+0

Pourquoi ne pas simplement ajouter un AddRange (IEnumerable articles) à votre classe de collection? – BFree

+0

Mode, beauté et style. Je pourrais mais je me demandais si je pourrais le faire d'une autre manière aussi. – danmine

Répondre

3

Vous devez renvoyer void à partir de Add comme cela est défini dans ICollection. Cela exclut la méthode Add chaînée en ne prenant qu'un paramètre, je crois.

Pas tout à fait ce que vous voulez mais vous pourriez ajouter quelque chose comme ceci à votre type de collection personnalisé.

public CustomCollectionType Append(string toAdd) 
{ 
    this.Add(string toAdd); 
    return this; 
} 

Ensuite, vous pouvez faire:

customCollection.Append("This").Append("Does").Append("Chain"); 

espoir qui aide,

Dan

+0

+1 pour utiliser Ajouter au lieu de Ajouter. Tous les endroits dont je peux me souvenir ont Add return void ou l'item. Jamais la collection. Avoir ajouter retourne la sorte de collection brise une convention. –

0

Vous pouvez cacher ICollection.Add méthode dans votre classe de collection personnalisée et retourner ce.

public class MyList<T>:List<T> 
{ 
    public new MyList<T> Add(T item) 
    { 
    (this as ICollection<T>).Add(item); 
    return this; 
    } 
} 

vous pouvez ajouter l'article à chaînés Ajouter appels:

MyList<string> strList = new MyList<string>(); 
strList.Add("Hello").Add(" ").Add("World!"); 
+0

Est-il toujours possible d'implémenter ICollection dans la classe de collection personnalisée de cette manière? –

+0

Si vous implémentez ICollection implicitement, je ne pense pas car vous auriez alors deux méthodes Add avec la même signature dans la même classe. Ils ne différeront que par le type de retour mais le compilateur ne considère pas le type de retour pour différencier les surcharges de méthode. Toutefois, si vous implémentez ICollection explicitement, les deux méthodes Add peuvent exister ensemble. –

+0

Il sera bon de connaître la raison pour laquelle les downvotes sont disponibles. –

2

Une autre option serait d'utiliser C# collection initialiseur:

var list = new YourList<String>() 
    { 
     "Hello", 
     "World", 
     "etc..." 
    }; 
5

Vous pouvez également utiliser une méthode d'extension serait utilisable avec n'importe quel ICollection<T> et vous évite d'écrire votre propre classe de collection:

public static ICollection<T> ChainAdd<T>(this ICollection<T> collection, T item) 
{ 
    collection.Add(item); 
    return collection; 
} 
11

Tout fluide est agréable, je serais plus intéressé à ajouter un AddRange (ou deux):

public static void AddRange<T>(this ICollection<T> collection, 
    params T[] items) 
{ 
    if(collection == null) throw new ArgumentNullException("collection"); 
    if(items == null) throw new ArgumentNullException("items"); 
    for(int i = 0 ; i < items.Length; i++) { 
     collection.Add(items[i]); 
    } 
} 
public static void AddRange<T>(this ICollection<T> collection, 
    IEnumerable<T> items) 
{ 
    if (collection == null) throw new ArgumentNullException("collection"); 
    if (items == null) throw new ArgumentNullException("items"); 
    foreach(T item in items) { 
     collection.Add(item); 
    } 
} 

L'approche params T[] permet AddRange(1,2,3,4,5) etc, et le IEnumerable<T> permet d'utiliser avec des choses comme les requêtes LINQ.

Si vous souhaitez utiliser une API couramment, vous pouvez également écrire Append comme méthode d'extension en C# 3.0 qui préserve le type de liste originale, par l'utilisation appropriée des contraintes génériques:

public static TList Append<TList, TValue>(
     this TList list, TValue item) where TList : ICollection<TValue> 
    { 
     if(list == null) throw new ArgumentNullException("list"); 
     list.Add(item); 
     return list; 
    } 
    ... 
    List<int> list = new List<int>().Append(1).Append(2).Append(3); 

(note il retourne List<int>)

+0

Je suis confus ... pourquoi n'est-ce pas la réponse la mieux notée et acceptée ?! –

0

Aucune infraction, mais peut-être vous préférez VB.NET

il est plus propice à la programmation « langage naturel » que C# est.

Dans VB.NET vous avez le « avec » la construction qui vous permettra de faire: Méthode

With myCollection 
    .Add("Hello") 
    .Add("There") 
    .Add("My") 
    .Add("Name") 
    .Add("Is") 
    .Add("Silky") 
    .Sort() 
End With