Class methods in D?

Steven Schveighoffer schveiguy at yahoo.com
Thu May 3 10:45:20 PDT 2012


On Thu, 03 May 2012 13:21:55 -0400, Mehrdad <wfunction at hotmail.com> wrote:

> In Windows, you need to register a "window class" before you can  
> actually create an instance of it.
>
> Mapping this idea to D (and most other languages, I admit) is hard.  
> Microsoft's solution in C# is pretty ugly.
>
> The problem is this:
> You make a class like
> class Window
> {
>     HWND handle;
>     virtual @property string className()  // How the system identifies  
> this subclass
>     { /*some default code for lazily registering a class*/ }
>     this() { this.handle = className(this.className, ...); }
> }
> which people are supposed to inherit from.
>
> The trouble is that there is *no clean way* (that I can think of) to  
> ensure this:
> if (typeid(windowA) == typeid(windowB))
> { assert(windowA.className == windowB.className); }
>
> This is necessary in order to make sure that the idea of a "class" in D  
> is the same as the one that the system sees.
>
> If className() was class method, this assumption would be trivial to  
> ensure: subclasses could override it, and it would be the same for all  
> instances of the class. It would map to OOP in D **VERY** cleanly.
> Right now, though, it's a big pain to map this concept... and the lack  
> of proper reflection isn't helping.
> (Microsoft just decided to make it an instance property, but if you look  
> at the code, you'll see it's infinitely ugly...)
>
> Is there any chance that we can get (overridable) class methods in D?
> If not, is there a good solution to this problem?
> (At least, will it be possible to retrieve the static methods of a class  
> with reflection?)

This works:

import std.stdio;

class A
{
   string name;
   this() {this.name = typeid(this).name;}
}

class B : A {}

void main()
{
    A b = new B;
    A a = new A;
    writefln("A: %s, B: %s", a.name, b.name);
}

outputs:

A: testclassname.A, B: testclassname.B

Do what you want with that name, not sure if the window class can have  
dots in it... (I haven't done much low-level GUI work on windows).

Why does this work?  Because typeid(obj) gets the TypeInfo based on the  
object's *derived* type, not it's static type.  Since the typeinfo is  
properly set before the ctor is called, this means you get the correct  
type.  Also, note if there is anything you need via the TypeInfo, it's  
accessible.  Given the recent additions to the compiler and the RTInfo  
template, you should be able to generate everything you need.

-Steve


More information about the Digitalmars-d mailing list