This articleneeds additional citations forverification. Please helpimprove this article byadding citations to reliable sources. Unsourced material may be challenged and removed. Find sources: "Method chaining" – news ·newspapers ·books ·scholar ·JSTOR(May 2008) (Learn how and when to remove this message) |
Method chaining is a commonsyntax for invoking multiple method calls inobject-oriented programming languages. Each method returns an object, allowing the calls to be chained together in a single statement without requiring variables to store the intermediate results.
Local variable declarations aresyntactic sugar.[1]
Method chaining eliminates an extra variable for each intermediate step. The developer is saved from the cognitive burden of naming the variable and keeping the variable in mind.
Method chaining has been referred to as producing a "train wreck" due to the increase in the number of methods that come one after another in the same line that occurs as more methods are chained together.[2]
A similar syntax ismethod cascading, where after the method call the expression evaluates to the current object, not thereturn value of the method. Cascading can be implemented using method chaining by having the method return thecurrent object itself. Cascading is a key technique influent interfaces, and since chaining is widely implemented in object-oriented languages while cascading isn't, this form of "cascading-by-chaining by returningthis" is often referred to simply as "chaining". Both chaining and cascading come from theSimula language.
While chaining is syntax, it has semantic consequences, namely that requires methods to return an object, and if implementing cascading via chaining, this must be the current object. This prevents the return value from being used for some other purpose, such as returning anerror value.
A common example isstd::istream andstd::ostream (the input and output stream classes) inC++, where for example<< returns the left object, allowing chaining.[3]
a<<b<<c;// this is equivalent to:a<<b;a<<c;
Functional programming is another example of the usage of method chaining, involving higher-order functions. Inobject-oriented programming, higher-order functions and manipulation of collections can be represented through methods that are chained together.[4]
One such example inJava uses the built-in methods ofjava.util.stream.Stream<E>:
importjava.util.Arrays;importjava.util.List;importjava.util.streams.Collectors;// ...List<Integer>numbers=Arrays.asList(10,25,30,45,60,75,90);List<Integer>result=numbers.stream()// .stream() returns java.util.stream.Stream.filter(n->n>30).map(n->n*2).sorted().collect(Collectors.toList());
Note that in Java,filter(),map(), andsorted() return a new shallow copy of the preceding list. However, to operate on the list in-place, thesort() method can be used.[5]
Language Integrated Query (or LINQ) forC# makes extensive usage of method chaining.[6]
usingSystem;usingSystem.Collections;// using method chaining:IEnumerble<MyObject>results=SomeCollection.Where(c=>c.SomeProperty<10).Select(c=>new{c.SomeProperty,c.OtherProperty});results.ForEach(x=>{Console.WriteLine(x.ToString());});// using LINQ keywords:IEnumerable<MyObject>results=fromcinSomeCollectionwherec.SomeProperty<10selectnew{c.SomeProperty,c.OtherProperty};foreach(MyObjectresultinresults){Console.WriteLine(result);}
C++20 introducesoperator| (the piping operator) and allows LINQ-style chaining operations with thestd::ranges namespaces.std::views contains several classes which are invoked throughoperator().[7]
importstd;usingstd::vector;usingstd::ranges::to;usingstd::views::filter;usingstd::views::transform;vector<int>numbers={1,2,3,4,5,6,7,8,9,10};// Pipeline: filter even numbers, double them, and then sum the resultvector<int>result=numbers|filter([](intn)->bool{returnn%2==0;})|transform([](intn)->int{returnn*2;})|to<vector>();
The Builder pattern relies on constructing an object through method calls rather than immediately in its constructor. For example,java.lang.StringBuilder makes use method chaining to build aStringBuilder.[8]
StringBuildersb=newStringBuilder();Stringresult=sb.append("Hello, ").append("world!").insert(0,"Greeting: ").replace(10,18,"beautiful ").toString();
The Fluent interface pattern relies entirely on method chaining to implement method cascading.[9]
In C++, similar method chaining to Java and C# can be accomplished by having the methods return (for example, for a classStringBuilder,.append() and.replace() could have typeStringBuilder& and return*this). However, in C++ it is important to be conscious of potentialobject slicing if the returned reference is to a parent class, while other languages such as Java, C#, andRust are not subject to this problem.[10][11]
• Syntactic sugar for local declarations - let x = e1 in e2 is short for (λx.e2) e1
{{cite book}}:|website= ignored (help)