Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c#

.net

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?

like image 907
AJ Henley Avatar asked Mar 30 '12 04:03

AJ Henley


People also ask

How do you define a class in C?

C Classes A class consists of an instance type and a class object: An instance type is a struct containing variable members called instance variables and function members called instance methods. A variable of the instance type is called an instance.

Can we use class in C?

No, C doesn't have classes. That said, there are ways of simulating object-oriented programming in C - a quick Google search should yield some useful results.

Which keyword is used to create a class in C?

The class keyword is used to create a class called MyClass . The public keyword is an access specifier, which specifies that members (attributes and methods) of the class are accessible from outside the class.


4 Answers

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.

like image 108
devio Avatar answered Oct 03 '22 22:10

devio


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

ClassName foo()
{
    return this;
}
like image 35
Lander Avatar answered Oct 03 '22 22:10

Lander


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

like image 26
gideon Avatar answered Oct 03 '22 21:10

gideon


This should get you close.

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

        return this;
    }
}

Good luck, Tom

like image 32
Thomas Avatar answered Oct 03 '22 21:10

Thomas