Traits

Jonathan M Davis jmdavisProg at gmx.com
Fri Oct 11 14:49:40 PDT 2013


On Friday, October 11, 2013 23:06:53 luminousone wrote:
> On Friday, 11 October 2013 at 19:54:39 UTC, Jonathan M Davis
> 
> wrote:
> > On Friday, October 11, 2013 21:19:29 luminousone wrote:
> >> Using casts that way won't always be correct, it would be
> >> better
> >> to use reflection in some way if possible.
> > 
> > The only reason that the casts wouldn't be correct would be if
> > the class
> > overrode opCast for the type that you're casting to or had an
> > alias this
> > declaration for it. Using casting for "instanceOf" is
> > considered the standard
> > and correct way to do it. But if you're being paranoid about
> > the possibility
> > of a conversion being defined with opCast or alias this, then
> > yes, you need to
> > use typeid.
> > 
> > - Jonathan M Davis
> 
> import std.stdio;
> 
> bool instanceOf(A, B)(B value) {
> return !!cast(A)value;
> }
> 
> class e {
> }
> 
> class f : e {
> 
> }
> 
> class g {
> 
> }
> 
> 
> void main() {
> int a;
> float b;
> char c;
> 
> e E;
> f F;
> g G;
> 
> assert( 1.instanceOf!int, "1");
> assert( a.instanceOf!int, "a"); // fails here ?!?
> assert( b.instanceOf!int, "b");
> assert( c.instanceOf!int, "c");
> 
> assert( E.instanceOf!e , "e"); // fails here !??
> assert( F.instanceOf!e , "f");
> assert( G.instanceOf!e , "g"); // fails as expected
> }
> 
> 
> Seems to be problems, at least with quick testing using rdmd.
> Using casts seems terribly hackish, I would think that some sort
> of reflection should be much safer/correct way todo this.

Two things:

1. Casting to determine the type of a variable only makes sense with classes. 
The idea is that casting a reference to a particular class will result in null 
if the cast fails. That doesn't work at all with types that aren't classes.

2. All of your objects are null. Of course the cast is going to fail. You need 
to be operating on actual instances. The whole point of casting is to check 
the actual type of an object at runtime. It's a completely different use case 
from using compile-time reflection on two types to see whether one is a base 
class of the other. And usually all that's done for that is to see whether one 
implicitly converts to the other, which is(DerivedClass : BaseClass) will do 
for you. The only reason to use compile-time reflection is if you're want to 
make sure that DerivedClass doesn't implicitly convert to BaseClass via alias 
this instead of by actually being a class derived from BaseClass.

I'd also change the implementation of instanceOf to something like

bool instanceOf(A, B)(B value)
 if(is(A == class) && is(B == class))
{
 return cast(A)value !is null;
}

since it doesn't rely on the conversion to bool that ! does and is more 
explicit that way, but the other version will work.

- Jonathan M Davis


More information about the Digitalmars-d-learn mailing list