Method-Chaining in C#

C#

C# Problem Overview


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

C# Solutions


Solution 1 - C#

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

Solution 2 - C#

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".

Solution 3 - C#

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

Solution 4 - C#

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

Solution 5 - C#

Why don't you use the params keyword?

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

Solution 6 - C#

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

Solution 7 - C#

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.

Solution 8 - C#

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

Solution 9 - C#

Something like this?

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionPatrickView Question on Stackoverflow
Solution 1 - C#LBushkinView Answer on Stackoverflow
Solution 2 - C#UserView Answer on Stackoverflow
Solution 3 - C#Marc GravellView Answer on Stackoverflow
Solution 4 - C#Jon SkeetView Answer on Stackoverflow
Solution 5 - C#bruno condeView Answer on Stackoverflow
Solution 6 - C#GC.View Answer on Stackoverflow
Solution 7 - C#Martin LiversageView Answer on Stackoverflow
Solution 8 - C#Tim HoolihanView Answer on Stackoverflow
Solution 9 - C#Mats FredrikssonView Answer on Stackoverflow