Thread overview
testing if an instance is a subclass of a given class
Sep 17, 2008
Paul Dufresne
Sep 17, 2008
BCS
Sep 17, 2008
downs
Sep 17, 2008
downs
September 17, 2008
Well, I have decided that translating Python code to D would be a nice way to learn D.
It clearly shows me how D is a statically-typed language, and Python a dynamically-typed language.

I'd like to translate to D:
  if issubclass(type(item), Base):
    item.on_value_changed(True)
  elif issubclass(type(item), Group):
    item.on_last_change()

My problem is to translate issubclass.

using typeid(item) I would get some info about the type... but it is unclear how to test for subclass from there.

item is(item:Base) is a compile-time test, so it does not seems to do what I want.

I am thinking about something like:
if (cast (Base) item)!=null then
     item.on_value_changed(True);
else if (cast(Group) item)!=null then
        item.on_last_change();

oh... as I am writing I see the suggestion in spec_DMD_1.00.pdf to do:
In order to determine if an object o is an instance of a class B use a cast:
if (cast(B) o)
{
     // o is an instance of B
}
else
{
     // o is not an instance of B
}

My guess is that it is really a subclassing test... is it?

And would it be possible to write an isSubclass function in D based on this test...
I don't see how I would pass the Class for the test... what come in mind naturally would be:
bool isSubclass (Class C, Object o){
  if (cast (C o) then return true else return false;
}

but the Class type does probably not exist ... does it?
September 17, 2008
reading only the subject


class C {}
class B : C {}
class A : C {}

C c = somthing();

if(auto b = cast(B)c)
{
 // is a B, use b
}


September 17, 2008
Paul Dufresne wrote:
> And would it be possible to write an isSubclass function in D based on this test...
> I don't see how I would pass the Class for the test... what come in mind naturally would be:
> bool isSubclass (Class C, Object o){
>   if (cast (C o) then return true else return false;
> }
> 
> but the Class type does probably not exist ... does it?

Close.

bool isA(T)(Object obj) {
  return (cast(T) obj)?true:false;
}

..

class A { }
class B : A { }

A x = new B;

if (isA!(B)(x)) { } else { }

Note however, that this is an exercise in redundancy, as it is almost exactly the same as "if (cast(B) x)".

I really recommend you use that instead.
September 17, 2008
downs wrote:
> Paul Dufresne wrote:
>> And would it be possible to write an isSubclass function in D based on this test...
>> I don't see how I would pass the Class for the test... what come in mind naturally would be:
>> bool isSubclass (Class C, Object o){
>>   if (cast (C o) then return true else return false;
>> }
>>
>> but the Class type does probably not exist ... does it?
> 
> Close.
> 
> bool isA(T)(Object obj) {
>   return (cast(T) obj)?true:false;
> }
> 
> ..
> 
> class A { }
> class B : A { }
> 
> A x = new B;
> 
> if (isA!(B)(x)) { } else { }
> 
> Note however, that this is an exercise in redundancy, as it is almost exactly the same as "if (cast(B) x)".
> 
> I really recommend you use that instead.

In fact, there's a nifty idiom that exploits the fact that you can create a variable in an if statement ..

A x = new B;

if (auto xAsB = cast(B) x) { /* do op on xAsB */ }