On Thu, 06 Mar 2014 14:04:48 -0500, Gary Willoughby <[email protected]> wrote:
I'm trying to create methods across class hierarchies that can be
chained nicely but i'm running into the problem that 'this' declared in
a parent class only refers to that type. Is there a way i can get the
following code to perform in the way i expect?
import std.stdio;
class Foo
{
public auto foo()
{
return this;
}
}
class Bar : Foo
{
public auto bar()
{
return this;
}
}
void main(string[] args)
{
Bar bar = new Bar().bar().foo();
}
test2.d(21): Error: cannot implicitly convert expression ((new
Bar).bar().foo()) of type test2.Foo to test2.Bar
Failed: 'dmd' '-v' '-o-' 'test2.d' '-I.'
How can i make the above marked 'this' refer to Bar when being called in
a chain? When i call the methods like this each method call seems to
implicitly convert 'this' into that method's containing class' instance,
breaking the code and sometimes hiding child methods.
There are two possibilities.
First, you can create a non-virtual function, which can be templated on
the type called with:
T foo(this T)() // T == whatever type you called the method as.
{
return cast(T)this; // the cast is necessary because inside foo, 'this'
is base class type
}
Second, you can override the function in subsequent classes:
class Bar : Foo
{
public auto foo() { return this;}
}
And of course, if you just want to inherit the implementation:
public auto foo() { return cast(Foo)super.foo();}
This gets tricky if you are not certain of the base implementation. If it
could ever return a "Foo" that is not actually 'this', then the function
will likely not work correctly.
I had proposed, a long time ago, a mechanism to note that a function
should always return 'this', and the compiler could take that into account
(enforce it, and make assumptions based on the type called with). The
response I got was to use the template form.
-Steve