AJ Henley
AJ Henley

Reputation: 85

How do I declare a class in C# so that I can chain methods?

I have a custom class that I use to build table strings. I would like to rewrite the code so that I can chain the operators. Something like:

myObject
  .addTableCellwithCheckbox("chkIsStudent", isUnchecked, isWithoutLabel)
  .addTableCellwithTextbox("tbStudentName", isEditable) etc.

So it seems like I would have each of these methods(functions) return the object itself so that I can then call another method(function) on the resulting object, but I can't figure out how to get a c# class to refer to itself.

Any help?

Upvotes: 5

Views: 294

Answers (5)

Lander
Lander

Reputation: 3437

Use the this keyword as the return value, that way you return itself and you can chain forever:

ClassName foo()
{
    return this;
}

Upvotes: 7

gideon
gideon

Reputation: 19465

So you would create a fluent interface like this:

class FluentTable 
{
  //as a dumb example I'm using a list
  //use whatever structure you need to store your items
  List<string> myTables = new List<string>();

  public FluentTable addTableCellwithCheckbox(string chk, bool isUnchecked, 
                                                        bool  isWithoutLabel)
  {
    this.myTables.Add(chk);
    //store other properties somewhere
    return this;
  }

  public FluentTable addTableCellwithTextbox(string name, bool isEditable)
  {
    this.myTables.Add(name);
    //store other properties somewhere
    return this;
  }
  public static FluentTable New()
  {
    return new FluentTable();
  }
}

Now you could use it like this:

  FluentTable tbl = FluentTable
                    .New()
                    .addTableCellwithCheckbox("chkIsStudent", true, false)
                    .addTableCellwithTextbox("tbStudentName", false);

This should give you a basic idea of how you need to go about it. See fluent interfaces on wikipedia.

A more correct way to do it would be to implement a fluent interface:

interface IFluentTable
{
 IFluentTable addTableCellwithCheckbox(string chk, bool isUnchecked, 
                                                        bool  isWithoutLabel)
 IFluentTable addTableCellwithTextbox(string name, bool isEditable)
 //maybe you could add the static factory method New() here also 
}

And then implement it : class FluentTable : IFluentTable {}

Upvotes: 6

devio
devio

Reputation: 37205

This notation is called Fluent.

For your example, the simplest form would be

public class MyObject {
    public MyObject addTableCellwithCheckbox(...) { 
        ... 
        return this;
    }
    public MyObject addTableCellwithTextbox(...) {
        ...
        return this;
    }
}

In the more beautiful form, you declare interfaces (for example, IMyObject) with these methods, and have the MyObject class implement that interface. The return type must be the interface, as illustrated in the Wikipedia example above.

If the source code of the class is not accessible, you can also implement an extension class in a similar way.

Upvotes: 7

Thomas
Thomas

Reputation: 3560

This should get you close.

public class SomeObject
{ 
    public SomeObject AddTableCellWithCheckbox(string cellName, bool isChecked)
    {
        // Do your add.

        return this;
    }
}

Good luck, Tom

Upvotes: 3

TGH
TGH

Reputation: 39248

Make sure that each method returns an interface that declares methods that you want to call on your chain.

EX public IAdd Add()

This way if IAdd defined an add method you can call Add after Add after Add. You can obviously add otterh methods to the same interface as well. This is typically called a fluent API

Upvotes: 0

Related Questions