Thread overview |
---|
November 21, 2014 how to compare the type of a subclass | ||||
---|---|---|---|---|
| ||||
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 |
November 21, 2014 Re: how to compare the type of a subclass | ||||
---|---|---|---|---|
| ||||
Posted in reply to Eric | 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));
|
November 21, 2014 Re: how to compare the type of a subclass | ||||
---|---|---|---|---|
| ||||
Posted in reply to anonymous | 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.
|
November 21, 2014 Re: how to compare the type of a subclass | ||||
---|---|---|---|---|
| ||||
Posted in reply to Eric | 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. |
November 21, 2014 Re: how to compare the type of a subclass | ||||
---|---|---|---|---|
| ||||
Posted in reply to Eric | 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. |
November 21, 2014 Re: how to compare the type of a subclass | ||||
---|---|---|---|---|
| ||||
Posted in reply to H. S. Teoh | 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
|
Copyright © 1999-2021 by the D Language Foundation