Patrick
Patrick

Reputation: 1783

Method-Chaining in C#

I have actually no idea of what this is called in C#. But i want to add the functionallity to my class to add multiple items at the same time.

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

Upvotes: 81

Views: 75055

Answers (9)

Jon Skeet
Jon Skeet

Reputation: 1500385

Others have answered in terms of straight method chaining, but if you're using C# 3.0 you might be interested in collection initializers... they're only available when you make a constructor call, and only if your type has appropriate Add methods and implements IEnumerable, but then you can do:

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

Upvotes: 12

GC.
GC.

Reputation: 1244

You could add an extension method to support this, provided your class inherits from 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;
    }
}

Upvotes: 6

LBushkin
LBushkin

Reputation: 131676

The technique you mention is called chainable methods. It is commonly used when creating DSLs or fluent interfaces in C#.

The typical pattern is to have your AddItem() method return an instance of the class (or interface) it is part of. This allows subsequent calls to be chained to it.

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

   return this;
}

Some alternatives to method chaining, for adding items to a collection, include:

Using the params syntax to allow multiple items to be passed to your method as an array. Useful when you want to hide the array creation and provide a variable argument syntax to your methods:

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 );

Providing an overload of type IEnumerable or IEnumerable so that multiple items can be passed together to your collection class.

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

Use .NET 3.5 collection initializer syntax. You class must provide a single parameter Add( item ) method, implement IEnumerable, and must have a default constructor (or you must call a specific constructor in the initialization statement). Then you can write:

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

Upvotes: 134

bruno conde
bruno conde

Reputation: 48265

Why don't you use the params keyword?

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

Upvotes: 5

User
User

Reputation: 30945

Use this trick:

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;
    }
}

It returns the current instance which will allow you to chain method calls (thus adding multiple objects "at the same time".

Upvotes: 35

Marc Gravell
Marc Gravell

Reputation: 1062745

"I have actually no idea of what this is called in c#"

A fluent API; StringBuilder is the most common .NET example:

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

Upvotes: 20

Martin Liversage
Martin Liversage

Reputation: 106826

How about

AddItem(ICollection<Item> items);

or

AddItem(params Item[] items);

You can use them like this

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

This is not method chaining, but it adds multiple items to your object in one call.

Upvotes: 3

Mats Fredriksson
Mats Fredriksson

Reputation: 20101

Something like this?

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

Upvotes: 1

Tim Hoolihan
Tim Hoolihan

Reputation: 12396

If your item is acting as a list, you may want to implement an interface like iList or iEnumerable / iEnumerable.

Regardless, the key to chaining calls like you want to is returning the object you want.

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

Upvotes: 1

Related Questions