runtime type and that bizarre "is()"

BCS anon at anon.com
Sun Nov 14 08:07:01 PST 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




More information about the Digitalmars-d-learn mailing list