Thread overview
Re: runtime type and that bizarre "is()"
Nov 14, 2010
Jonathan M Davis
Nov 14, 2010
BCS
Nov 14, 2010
spir
November 14, 2010
On Sunday 14 November 2010 03:45:12 spir wrote:
> Hello,
> 
> 
> Is there a way to check the runtime type of an element? Meaning, for instance, process differently according to the actual type in a hierarchy?
> 
> class C {}
> class C1 : C {int i;}
> bool checkTypeC1 (C c) {
>     return is(typeof(c) == C1);
> }
> void main () {
>     C1 c1 = new C1();
>     writeln(is(typeof(c1) == C1));  // true, indeed!
>     writeln(checkTypeC1(c1));       // false!
>     C c = new C1();
>     writeln(is(typeof(c) == C1));   // false!
> }
> 
> If, above, checktype is actualy a func that does more according to c's type (or is called by a func that does more), then it bugs. Should one write overloaded versions of the func depending on param type? But what about common parts of the process (sometimes, the difference is tiny)? One can factorise out into an additional func, but then there is func call overhead, and the code structure gets complexified.
> 
> Also, I would like to ask about "is()". I don't understand its logics and
> uses, even after reading TDPL pages about it. Seems uselessly complicated
> and unintuitive. For instance, in the above cases, why do I need is() at
> all? Why not just "typeof(c) == C1"? or even better "typeof(c) is C1"? By
> the way, why is "is(typeof(c) is C1)" refused by the compiler? It's more
> logical than "==", imo, as types should be compared by identity, not
> value. (For instance, 2 structs or classes that happen to define
> identically named and typed fields are _not_ the same, unique, type.)

If you are dealing with a class hierarchy and you want to know whether a base class reference referes to a particular derived class object, I believe that the correct way to do it is cast it to the derived type and check whether it is null. If it's non-null, then it is that derived type. If it's null, then it isn't.

- Jonathan M Davis
November 14, 2010
On Sun, 14 Nov 2010 04:09:22 -0800
Jonathan M Davis <jmdavisProg@gmx.com> wrote:

> If you are dealing with a class hierarchy and you want to know whether a base class reference referes to a particular derived class object, I believe that the correct way to do it is cast it to the derived type and check whether it is null. If it's non-null, then it is that derived type. If it's null, then it isn't.

Oh, yes, thank you very much, Jonathan.

denis
-- -- -- -- -- -- --
vit esse estrany ☣

spir.wikidot.com

November 14, 2010
Hello Jonathan,

> On Sunday 14 November 2010 03:45:12 spir wrote:
> 
>> Hello,
>> 
>> Is there a way to check the runtime type of an element? Meaning, for
>> instance, process differently according to the actual type in a
>> hierarchy?
>> 
>> class C {}
>> class C1 : C {int i;}
>> bool checkTypeC1 (C c) {
>> return is(typeof(c) == C1);
>> }
>> void main () {
>> C1 c1 = new C1();
>> writeln(is(typeof(c1) == C1));  // true, indeed!
>> writeln(checkTypeC1(c1));       // false!
>> C c = new C1();
>> writeln(is(typeof(c) == C1));   // false!
>> }
>> If, above, checktype is actualy a func that does more according to
>> c's type (or is called by a func that does more), then it bugs.
>> Should one write overloaded versions of the func depending on param
>> type? But what about common parts of the process (sometimes, the
>> difference is tiny)? One can factorise out into an additional func,
>> but then there is func call overhead, and the code structure gets
>> complexified.
>> 
>> Also, I would like to ask about "is()". I don't understand its logics
>> and uses, even after reading TDPL pages about it. Seems uselessly
>> complicated and unintuitive. For instance, in the above cases, why do
>> I need is() at all? Why not just "typeof(c) == C1"? or even better
>> "typeof(c) is C1"? By the way, why is "is(typeof(c) is C1)" refused
>> by the compiler? It's more logical than "==", imo, as types should be
>> compared by identity, not value. (For instance, 2 structs or classes
>> that happen to define identically named and typed fields are _not_
>> the same, unique, type.)
>> 
> If you are dealing with a class hierarchy and you want to know whether
> a base class reference referes to a particular derived class object, I
> believe that the correct way to do it is cast it to the derived type
> and check whether it is null. If it's non-null, then it is that
> derived type. If it's null, then it isn't.

That checks that the object in question is of the derived type /or a type derived from it/. Most of the time that will be what you want. If you want to exclude the second bit: typeid(obj) is your friend (and dynamic libs become your nemesis).

http://www.digitalmars.com/d/2.0/expression.html#TypeidExpression
http://www.digitalmars.com/d/2.0/operatoroverloading.html#equals