2009-07-13 10 views
48

Non ho idea di ciò che viene chiamato in C#. Ma voglio aggiungere la funzionalità alla mia classe per aggiungere più oggetti allo stesso tempo.Concatenamento in C#

myObj.AddItem(mItem).AddItem(mItem2).AddItem(mItem3); 

risposta

89

La tecnica che si menziona si chiama metodi concatenabili. Viene comunemente utilizzato durante la creazione di DSL o fluent interfaces in C#.

Lo schema tipico prevede che il metodo AddItem() restituisca un'istanza della classe (o dell'interfaccia) di cui fa parte. Ciò consente di concatenare le chiamate successive.

public MyCollection AddItem(MyItem item) 
{ 
    // internal logic... 

    return this; 
} 

Alcune alternative al metodo di concatenamento, per l'aggiunta di elementi a una raccolta, comprendono:

Utilizzando la sintassi params per consentire a più elementi da passare al metodo come un array. Utile quando si vuole nascondere la creazione matrice e fornire una sintassi di argomenti variabili ai vostri metodi:

public void AddItems(params MyItem[] items) 
{ 
    foreach(var item in items) 
     m_innerCollection.Add(item); 
} 

// can be called with any number of arguments... 
coll.AddItems(first, second, third); 
coll.AddItems(first, second, third, fourth, fifth); 

Fornire un sovraccarico di tipo IEnumerable o IEnumerable in modo che le voci multiple possono essere passati insieme alla classe collezione.

public void AddItems(IEnumerable<MyClass> items) 
{ 
    foreach(var item in items) 
     m_innerCollection.Add(item); 
} 

Usa NET 3.5 raccolta sintassi di inizializzazione. La classe deve fornire un metodo con parametro singolo Add(item), implementare IEnumerable e deve avere un costruttore predefinito (oppure è necessario chiamare un costruttore specifico nell'istruzione di inizializzazione).Poi si può scrivere:

var myColl = new MyCollection { first, second, third, ... }; 
+4

+1 per aver menzionato le interfacce fluenti e aver fornito un collegamento –

+1

+1 ho imparato cose nuove: D ho pensato che avrei dovuto fare un metodo diverso per il metodo chaning – GaryNg

+0

C'è un notevole riscontro di prestazioni se lo fai? – starbeamrainbowlabs

32

usare questo trucco:.

public class MyClass 
{ 
    private List<MyItem> _Items = new List<MyItem>(); 

    public MyClass AddItem (MyItem item) 
    { 
     // Add the object 
     if (item != null) 
      _Items.Add (item) 

     return this; 
    } 
} 

Esso restituisce l'istanza corrente, che vi permetterà di chiamate di metodo a catena (aggiungendo così più oggetti "allo stesso tempo"

+0

non hanno bisogno di limitare l'argomento AddItem per MyClass. Potrebbe probabilmente oggetto, o oggetto, o qualcosa del genere. –

1

Se il vostro articolo agisce come un elenco, si consiglia di implementare un'interfaccia come IList o IEnumerable/IEnumerable.

Indipendentemente da ciò, la chiave per il concatenamento chiamate come si vuole è tornare all'oggetto tu vuoi.

public Class Foo 
{ 
    public Foo AddItem(Foo object) 
    { 
     //Add object to your collection internally 
     return this; 
    } 
} 
1

Qualcosa di simile?

class MyCollection 
{ 
    public MyCollection AddItem(Object item) 
    { 
     // do stuff 
     return this; 
    } 
} 
3

Come su

AddItem(ICollection<Item> items); 

o

AddItem(params Item[] items); 

È possibile utilizzarli come questo

myObj.AddItem(new Item[] { item1, item2, item3 }); 
myObj.AddItem(item1, item2, item3); 

Questo non è il metodo di concatenazione, ma aggiunge più elementi al vostro oggetto in una chiamata.

12

"Non ho davvero idea di cosa questo è chiamato in C#"

Un API fluente; StringBuilder è l'esempio più comune di .NET:

var sb = new StringBuilder(); 
string s = sb.Append("this").Append(' ').Append("is a ").Append("silly way to") 
    .AppendLine("append strings").ToString(); 
10

Altri hanno risposto in termini di metodo di concatenamento dritto, ma se si sta utilizzando C# 3.0 potreste essere interessati a inizializzatori raccolta ... sono solo disponibile quando si effettua una chiamata al costruttore, e solo se il metodo ha appropriate Add metodi e implementa IEnumerable, ma poi si può fare:

MyClass myClass = new MyClass { item1, item2, item3 }; 
5

Perché non utilizzare la parola chiave params?

public void AddItem (params MyClass[] object) 
{ 
    // Add the multiple items 
} 
2

Si potrebbe aggiungere un metodo di estensione per sostenere questo, a condizione la classe eredita da ICollection:

[TestClass] 
public class UnitTest1 
{ 
    [TestMethod] 
    public void CanChainStrings() 
    { 
     ICollection<string> strings = new List<string>(); 

     strings.AddItem("Another").AddItem("String"); 

     Assert.AreEqual(2, strings.Count); 
    } 
} 
public static class ChainAdd 
{ 
    public static ICollection<T> AddItem<T>(this ICollection<T> collection, T item) 
    { 
     collection.Add(item); 
     return collection; 
    } 
}