www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - how to compare the type of a subclass

reply "Eric" <eric makechip.com> writes:
Suppose I have:

module test;
class X { }
class Y : X { }

Y y = new Y;

X x = y;

assert(is(typeof(x) == test.Y); // this assertion will fail
assert(typeid(x).toString() == "test.Y"); // this assertion will 
pass

Is there a way I can check the type of x without doing
a string comparison?

-Eric
Nov 21 2014
parent reply "anonymous" <anonymous example.com> writes:
On Friday, 21 November 2014 at 22:15:37 UTC, Eric wrote:
 Suppose I have:

 module test;
 class X { }
 class Y : X { }

 Y y = new Y;

 X x = y;

 assert(is(typeof(x) == test.Y); // this assertion will fail
 assert(typeid(x).toString() == "test.Y"); // this assertion 
 will pass

 Is there a way I can check the type of x without doing
 a string comparison?

 -Eric
assert(typeid(x) == typeid(Y));
Nov 21 2014
parent reply "Eric" <eric makechip.com> writes:
On Friday, 21 November 2014 at 22:25:32 UTC, anonymous wrote:
 On Friday, 21 November 2014 at 22:15:37 UTC, Eric wrote:
 Suppose I have:

 module test;
 class X { }
 class Y : X { }

 Y y = new Y;

 X x = y;

 assert(is(typeof(x) == test.Y); // this assertion will fail
 assert(typeid(x).toString() == "test.Y"); // this assertion 
 will pass

 Is there a way I can check the type of x without doing
 a string comparison?

 -Eric
assert(typeid(x) == typeid(Y));
Thanks. That works. I have't quite mastered the whole is/typeof/typeid thing yet.
Nov 21 2014
next sibling parent reply "H. S. Teoh via Digitalmars-d-learn" <digitalmars-d-learn puremagic.com> writes:
On Fri, Nov 21, 2014 at 10:30:51PM +0000, Eric via Digitalmars-d-learn wrote:
 On Friday, 21 November 2014 at 22:25:32 UTC, anonymous wrote:
On Friday, 21 November 2014 at 22:15:37 UTC, Eric wrote:
[...]
Is there a way I can check the type of x without doing
a string comparison?

-Eric
assert(typeid(x) == typeid(Y));
Thanks. That works. I have't quite mastered the whole is/typeof/typeid thing yet.
Binary `is` (i.e., `a is b`) is for comparing two references for equality. It returns true if two class reference point to the same object; false otherwise. But you probably already know this. Unary `is` (`is(...)`) is a monstrous maze of obscure syntax, that's best learned on a case-by-case basis. :-) But in this particular case, it's basically to provide a context for comparing types, since types aren't actual objects at runtime. So you can't write `if (typeof(a) == typeof(b))`, for example, because types aren't objects. Instead, you have to write `if (is(typeof(a) == typeof(b)))`. `typeof` is to extract types at compile-time. It returns the *declared* type of the variable (which may not be the most derived class if you assigned a derived object to a base class reference). `typeid` is to introspect types at runtime. It returns the most derived type of the object, even if the declared type is a base class. The returned type is an actual runtime object -- since at compile-time, the most derived type may not be known, so it's not representable as an actual type at compile-time. Instead, the D runtime returns a TypeInfo object that corresponds with the runtime type of the object. So you don't need to (and shouldn't) use `is(...)` when comparing typeid's. In short: To compare (declared) types at compile time: is(typeof(x) == typeof(y)) // x has the same (declared) type as y is(typeof(x) : typeof(y)) // x implicitly converts to y To compare (actual) types at runtime: typeid(x) == typeid(y) // x has the same (actual) time as y cast(B)x !is null // x is a derived class instance of base class B There are many other cases, of course, but these are the pertinent ones in the context of your original question. T -- Never wrestle a pig. You both get covered in mud, and the pig likes it.
Nov 21 2014
parent "Eric" <eric makechip.com> writes:
On Friday, 21 November 2014 at 22:52:54 UTC, H. S. Teoh via 
Digitalmars-d-learn wrote:
 On Fri, Nov 21, 2014 at 10:30:51PM +0000, Eric via 
 Digitalmars-d-learn wrote:
 On Friday, 21 November 2014 at 22:25:32 UTC, anonymous wrote:
On Friday, 21 November 2014 at 22:15:37 UTC, Eric wrote:
[...]
Is there a way I can check the type of x without doing
a string comparison?

-Eric
assert(typeid(x) == typeid(Y));
Thanks. That works. I have't quite mastered the whole is/typeof/typeid thing yet.
Binary `is` (i.e., `a is b`) is for comparing two references for equality. It returns true if two class reference point to the same object; false otherwise. But you probably already know this. Unary `is` (`is(...)`) is a monstrous maze of obscure syntax, that's best learned on a case-by-case basis. :-) But in this particular case, it's basically to provide a context for comparing types, since types aren't actual objects at runtime. So you can't write `if (typeof(a) == typeof(b))`, for example, because types aren't objects. Instead, you have to write `if (is(typeof(a) == typeof(b)))`. `typeof` is to extract types at compile-time. It returns the *declared* type of the variable (which may not be the most derived class if you assigned a derived object to a base class reference). `typeid` is to introspect types at runtime. It returns the most derived type of the object, even if the declared type is a base class. The returned type is an actual runtime object -- since at compile-time, the most derived type may not be known, so it's not representable as an actual type at compile-time. Instead, the D runtime returns a TypeInfo object that corresponds with the runtime type of the object. So you don't need to (and shouldn't) use `is(...)` when comparing typeid's. In short: To compare (declared) types at compile time: is(typeof(x) == typeof(y)) // x has the same (declared) type as y is(typeof(x) : typeof(y)) // x implicitly converts to y To compare (actual) types at runtime: typeid(x) == typeid(y) // x has the same (actual) time as y cast(B)x !is null // x is a derived class instance of base class B There are many other cases, of course, but these are the pertinent ones in the context of your original question. T
Thanks, this helps a lot. -Eric
Nov 21 2014
prev sibling parent "anonymous" <anonymous example.com> writes:
On Friday, 21 November 2014 at 22:30:52 UTC, Eric wrote:
 On Friday, 21 November 2014 at 22:25:32 UTC, anonymous wrote:
 On Friday, 21 November 2014 at 22:15:37 UTC, Eric wrote:
[...]
 class X { }
 class Y : X { }

 Y y = new Y;

 X x = y;
[...]
 I have't quite mastered the whole is/typeof/typeid
 thing yet.
Maybe this helps: There are two worlds: * the static world = the compile time world = the world of types and constant values, * the dynamic = the run time world = the world of values. Obviously, there are no variable values in the static world. Maybe less obviously, there are no types in the dynamic world. The variable x is statically typed as X. is(...) and typeof(...) operate on this level. But the object stored in x is being constructed as a Y at run time. That information is available through typeid. typeid(...) is not a type, it's a value of type TypeInfo which corresponds to a type. typeid(Y) and typeid(x) are TypeInfo objects both corresponding to the type Y.
Nov 21 2014