Thread overview
How to get child class Type and members from parent class?
Nov 20, 2019
zoujiaqing
Nov 20, 2019
mipri
Nov 20, 2019
Jacob Carlborg
Nov 20, 2019
Matheus
Nov 20, 2019
Adam D. Ruppe
Nov 21, 2019
zoujiaqing
November 20, 2019
import std.stdio;


class A
{
    this(T)(T t)
    {

    }

    void write()
    {
        T _this = cast(T) this;
        writeln(this.v);
    }
}

class B : A
{
    string v = "hello";
}

void main()
{
    auto b = new B;

    writeln(b.write()); // print hello
}
November 20, 2019
On Wednesday, 20 November 2019 at 10:05:11 UTC, zoujiaqing wrote:
> import std.stdio;
>
>
> class A
> {
>     this(T)(T t)
>     {
>
>     }
>
>     void write()
>     {
>         T _this = cast(T) this;
>         writeln(this.v);

Here, class A knows that a 'v' member is present. So why not just
put that member in class A, and let B inherit it?  If this method
won't apply to some other child classes, you can have an
intermediate class that adds the v member and specializes this
method to use it, and all the v children can inherit from A through
that intermediary.

I think what you're wanting to do is a reversal of OO design.
Maybe you can use proper OO instead, or maybe you'd prefer a
discriminated union if different children will have different types
for v. Like in an FP lang: https://github.com/pbackus/sumtype

>     }
> }
>
> class B : A
> {
>     string v = "hello";
> }
>
> void main()
> {
>     auto b = new B;
>
>     writeln(b.write()); // print hello
> }


November 20, 2019
On Wednesday, 20 November 2019 at 10:05:11 UTC, zoujiaqing wrote:
> import std.stdio;
>
>
> class A
> {
>     this(T)(T t)
>     {
>
>     }
>
>     void write()
>     {
>         T _this = cast(T) this;
>         writeln(this.v);
>     }
> }
>
> class B : A
> {
>     string v = "hello";
> }
>
> void main()
> {
>     auto b = new B;
>
>     writeln(b.write()); // print hello
> }

You can use a template this parameter [1], like this:

import std.stdio;

class A
{
    void write(this T)()
    {
        T self = cast(T) this;
        writeln(self.v);
    }
}

class B : A
{
    string v = "hello";
}

void main()
{
    auto b = new B;
    b.write();
}

[1] https://dlang.org/spec/template.html#template_this_parameter

--
/Jacob Carlborg
November 20, 2019
On Wednesday, 20 November 2019 at 13:46:07 UTC, Jacob Carlborg wrote:
> On Wednesday, 20 November 2019 at 10:05:11 UTC, zoujiaqing wrote:
>> import std.stdio;
>>
>>
>> class A
>> {
>>     this(T)(T t)
>>     {
>>
>>     }
>>
>>     void write()
>>     {
>>         T _this = cast(T) this;
>>         writeln(this.v);
>>     }
>> }
>>
>> class B : A
>> {
>>     string v = "hello";
>> }
>>
>> void main()
>> {
>>     auto b = new B;
>>
>>     writeln(b.write()); // print hello
>> }
>
> You can use a template this parameter [1], like this:
>
> import std.stdio;
>
> class A
> {
>     void write(this T)()
>     {
>         T self = cast(T) this;
>         writeln(self.v);
>     }
> }
>
> class B : A
> {
>     string v = "hello";
> }
>
> void main()
> {
>     auto b = new B;
>     b.write();
> }
>
> [1] https://dlang.org/spec/template.html#template_this_parameter
>
> --
> /Jacob Carlborg

I'm not the OP but a lurker, and this is new to me, I mean in your example you're accessing a member "v" which wasn't defined in the Parent class.

So if someone creates something like this:

class C : A{
    string x = "world";  // x instead of v
}

Not the "x" instead of "v", of course it will only get an compiler error if that function is called in by "C" object.

I think this is a powerful and weird feature at the same time, because some could write a code like this:

import std.stdio;

class A{
    void write(this T)(){
        T self = cast(T) this;
        writeln(self.v);
    }

    void write2(this T)(){
        T self = cast(T) this;
        writeln(self.x);
    }
}

class B : A{
    string v = "hello";
}

class C : A{
    string x = "world";
}

void main(){
    auto b = new B;
    b.write();

    auto c = new C;
    c.write2();
}

This is a different way of designing things, do people use this often?

Matheus.
November 20, 2019
On Wednesday, 20 November 2019 at 20:57:56 UTC, Matheus wrote:
> This is a different way of designing things, do people use this often?

This is really only useful sometimes.

It is important to notice that if you do

class C : I {}

I c = new C();
c.something();


the template this there will show I, not C. All it means is this is being called on an object of that *static* type. So it isn't really a substitute for traditional virtual functions.

Sometimes appropriate to use, just often not.
November 21, 2019
On Wednesday, 20 November 2019 at 22:26:17 UTC, Adam D. Ruppe wrote:
> On Wednesday, 20 November 2019 at 20:57:56 UTC, Matheus wrote:
>> This is a different way of designing things, do people use this often?
>
> This is really only useful sometimes.
>
> It is important to notice that if you do
>
> class C : I {}
>
> I c = new C();
> c.something();
>
>
> the template this there will show I, not C. All it means is this is being called on an object of that *static* type. So it isn't really a substitute for traditional virtual functions.
>
> Sometimes appropriate to use, just often not.

Thanks every friends :)