digitalmars.D.learn - how can i use the derive-hierarchy at runtime for typechecking?
- dennis luehring <dl.soluz gmx.net> Sep 20 2007
- Downs <default_357-line yahoo.de> Sep 20 2007
- Chris Nicholson-Sauls <ibisbasenji gmail.com> Sep 20 2007
- "Jarrett Billingsley" <kb3ctd2 yahoo.com> Sep 20 2007
- Chris Nicholson-Sauls <ibisbasenji gmail.com> Sep 20 2007
- "Jarrett Billingsley" <kb3ctd2 yahoo.com> Sep 20 2007
- dennis luehring <dl.soluz gmx.net> Sep 20 2007
- Regan Heath <regan netmail.co.nz> Sep 21 2007
- Downs <default_357-line yahoo.de> Sep 23 2007
is there a way to test at runtime if the type of an object is derived
from another object type? maybe with the help of compiletime-reflection
and additional information in the class?
class A{}
class B: A{}
class C: B{}
i need something like
B.type.is_derived_from( A.type ) ==> true
A.type.is_derived_from( C.type ) ==> false
B xx = new B;
B yy = new B;
xx.type == yy.type ==> true
is there an elegant way?
why do i need such stuff?
i use the normal D typechecking for the static part of my software
but i've got an GUI system with the ability to "construct" types
at runtime based on my static types (and i need a typesystem based on
the class hierachy for it)
thx dennis
Sep 20 2007
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Just cast it.
If you have class A { } and class B : A { }
and A foo=new B;
then you can do cast(B) foo and it will be non-null.
On the other hand, if you do A bar=new A;
and you do cast(B) bar, it will be null.
Here's a little utility function for this
void ifIs(S, T)(S obj, void delegate(T) dg) {
auto casted=cast(T) obj;
if (casted) dg(casted);
}
Use it like thus
ifIs(foo, (B whee) { /* do stuff with whee */ });
Hope that answers your question.
--downs/FeepingCreature
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iD8DBQFG8ugVpEPJRr05fBERAiazAKCn3BIgtWPuCPeONAgE4AZZZ5BPZwCgjwFh
GvztcB0FD5gA2U6sBA6pZsc=
=G05B
-----END PGP SIGNATURE-----
Sep 20 2007
Downs wrote:-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Just cast it. If you have class A { } and class B : A { } and A foo=new B; then you can do cast(B) foo and it will be non-null. On the other hand, if you do A bar=new A; and you do cast(B) bar, it will be null. Here's a little utility function for this void ifIs(S, T)(S obj, void delegate(T) dg) { auto casted=cast(T) obj; if (casted) dg(casted); } Use it like thus ifIs(foo, (B whee) { /* do stuff with whee */ });
And thanks to an oft-forgotten feature, you could shrink that down a little further to just a one-liner: void ifIs (S, T) (S obj, void delegate(T) dg) { if (auto casted = cast(T) obj) dg(casted); } http://digitalmars.com/d/1.0/statement.html#IfStatement -- Chris Nicholson-Sauls
Sep 20 2007
"Chris Nicholson-Sauls" <ibisbasenji gmail.com> wrote in message news:fcupko$kh7$2 digitalmars.com...void ifIs (S, T) (S obj, void delegate(T) dg) { if (auto casted = cast(T) obj) dg(casted); }
Or you could skip Downs' confusing way of writing code entirely ( ;) ) and just use: if(auto b = cast(B)foo) { // do stuff with b }
Sep 20 2007
Jarrett Billingsley wrote:"Chris Nicholson-Sauls" <ibisbasenji gmail.com> wrote in message news:fcupko$kh7$2 digitalmars.com...void ifIs (S, T) (S obj, void delegate(T) dg) { if (auto casted = cast(T) obj) dg(casted); }
Or you could skip Downs' confusing way of writing code entirely ( ;) ) and just use: if(auto b = cast(B)foo) { // do stuff with b }
Or we could add a new '?.' form for member access that becomes a nop on null references and just use: (cast(B) foo)?.doStuff(); Er.......... okay, that's just insane. -- Chris Nicholson-Sauls
Sep 20 2007
"Chris Nicholson-Sauls" <ibisbasenji gmail.com> wrote in message news:fcv1d1$vp6$1 digitalmars.com...Or we could add a new '?.' form for member access that becomes a nop on null references and just use: (cast(B) foo)?.doStuff(); Er.......... okay, that's just insane.
What do you think this is, Io?
Sep 20 2007
Jarrett Billingsley schrieb:"Chris Nicholson-Sauls" <ibisbasenji gmail.com> wrote in message news:fcupko$kh7$2 digitalmars.com...void ifIs (S, T) (S obj, void delegate(T) dg) { if (auto casted = cast(T) obj) dg(casted); }
Or you could skip Downs' confusing way of writing code entirely ( ;) ) and just use: if(auto b = cast(B)foo) { // do stuff with b }
and how can i insert this test in my base-class to hide the type stuff class base { int base_bla; bool is_derived_from( base other ) { auto check = cast(typeof(this))other; return !( check is null ); // why can't i compile this // return ( auto check = cast(typeof(this))other ); } } class test: base { int test_bla; } class blub: test { int blub_bla; } the is_derived_from test is always true maybe because of the base type parameter in is_derived_from and the other thing i need to know(show) the derive-hierachy "the hole story" in my c++ project i use objects which represents the type of an object for example class car // real implementation { } class car_class // object-type of class car { car create_instance(); ... bool is_derived_from base_class[] derived_from_me(); base_class[] base_class_of(); } and many [whatever]_class objects in my known-types-pool for example: i can ask which "types" i know i can create real types of it i can ask for the derives/bases of an "type" i can test if an "type" is hierachical "compatible"=derived from with another "type" and just need to know my base-class interface for doing this ... all this is done by using my own decription.language (with derive ability) and an c++ code generator... i hope to find a better (more compiletime based) way to get the same features - i want to get rid of this generator stuff ciao dennis
Sep 20 2007
dennis luehring wrote:Jarrett Billingsley schrieb:"Chris Nicholson-Sauls" <ibisbasenji gmail.com> wrote in message news:fcupko$kh7$2 digitalmars.com...void ifIs (S, T) (S obj, void delegate(T) dg) { if (auto casted = cast(T) obj) dg(casted); }
Or you could skip Downs' confusing way of writing code entirely ( ;) ) and just use: if(auto b = cast(B)foo) { // do stuff with b }
and how can i insert this test in my base-class to hide the type stuff class base { int base_bla; bool is_derived_from( base other ) { auto check = cast(typeof(this))other; return !( check is null ); // why can't i compile this
Because using 'auto' like this only works in an "if" statement. eg. if ( auto check = cast(typeof(this))other ) return true; return false;// return ( auto check = cast(typeof(this))other ); } } class test: base { int test_bla; } class blub: test { int blub_bla; } the is_derived_from test is always true maybe because of the base type parameter in is_derived_from
writefln(typeof(this).stringof) shows "base" even when called on an object of type "test" or "blub". So, even if you say: test t = new test; blub b = new blub; if (t.is_derived_from(b)) {} //is 'test' derived from 'blub' you're really just asking if t is derived from "base", which it is (has to be to have the is_derived_from method - in this case) Regan
Sep 21 2007
Jarrett Billingsley wrote:"Chris Nicholson-Sauls" <ibisbasenji gmail.com> wrote in message news:fcupko$kh7$2 digitalmars.com...void ifIs (S, T) (S obj, void delegate(T) dg) { if (auto casted = cast(T) obj) dg(casted); }
Or you could skip Downs' confusing way of writing code entirely ( ;) ) and just use: if(auto b = cast(B)foo) { // do stuff with b }
:surprised: --downs, learning new stuff every day! :)
Sep 23 2007









"Jarrett Billingsley" <kb3ctd2 yahoo.com> 