2010-05-28 6 views
6

Ich bemerkte die Funktion Object.factory (char [] className) in D. Aber es funktioniert nicht, wie ich es gehofft hatte, es würde funktionieren; es funktioniert nicht;)Get Klasseninstanz nach Klassenname String

Ein Beispiel:

import std.stdio; 

class TestClass 
{ 
    override string toString() 
    { 
     return typeof(this).stringof; // TestClass 
    } 
}; 

void main(string[] args) 
{ 
    auto i = Object.factory("TestClass"); 
    if (i is null) 
    { 
     writeln("Class not found"); 
    } 
    else 
    { 
     writeln("Class string: " ~ i); 
    } 
} 

ich denke, das in der Meldung zur Folge haben sollte: „Klasse string: Testclass“, aber es sagt: „Klasse nicht gefunden“.

Weiß jemand, warum das passiert und wie ich es beheben könnte?

Oder muss ich meine eigene Klassenfabrik machen. Zum Beispiel indem Sie eine Klasse mit einem statischen Array Object[string] classes; mit Klasseninstanzen erstellen. Wenn ich eine neue Instanz möchte ich dies:

auto i = (className in classes); 
if (i is null) 
{ 
    return null; 
} 
return i.classinfo.create(); 

EDIT:

Ich benutze es nun wie folgt aus (ein Beispiel, das für eine Web ist HMVC Muster):

class Page : Controller 
{ 
    static this() 
    { 
     register(Page.classinfo); 
    } 

    protected void registerActions() 
    { 
     registerAction("index", &index); 
    } 

    public void index() 
    { 
     request.response = "Page: " ~ request.params.get("pageID", "0") ~ " in format: " ~ request.params.get("format", "html"); 
    } 
}; 

void main(string[] args) 
{ 
    Route.add(
     r"page/(\d+)\.(html|json)", 
     [ 
      1: "pageID", 
      2: "format" 
     ], 
     [ 
      "controller": "page" // tell route to use page as controller class 
     ] 
    ); 
    Route.add(
     r"(\S+)/(\S+)", 
     [ 
      1: "controller", // get controller class from uri 
      2: "action" // get controller action from uri 
     ] 
    ); 

    auto request = Request.factory("/page/43.json").execute(); 

    // Headers and response can be accessed like this 
    // Can be used in http response 
    uint code = request.getCode(); 
    const(string[string]) headers = request.getHeaders(); 
    string response = request.response; 
} 

Diese Art von Material ist schwer in C++ zu tun;)

Antwort

6

Hier ist eine, die funktioniert:

module irc2; 

import std.stdio; 

class TestClass 
{ 
    override string toString() 
    { 
     return typeof(this).stringof; // TestClass 
    } 
}; 

void main(string[] args) 
{ 
    auto i = Object.factory("irc2.TestClass"); 
    if (i is null) 
    { 
     writeln("Class not found"); 
    } 
    else 
    { 
     writeln("Class string: " ~ i.toString); 
    } 
} 

Ein paar Dinge zu beachten:

  1. Sie haben die vollständig qualifizierten Klassennamen zu verwenden. Was, wenn Sie mehr als eine "TestClass" in Ihrem Programm hatten.
  2. Sie können kein Objekt an eine Zeichenfolge anhängen; Sie müssen toString verwenden. Das oder einfach writefln("Class string: %s", i) verwenden.
+0

Oder könnte man opCast (T: string) für die Klasse überladen und dann von selbst verketten? – 0scar

+0

Nein, weil ich vom Typ Objekt bin, den Sie nicht ändern können. Es ist einfacher // zu sagen, was Sie tun möchten: Verwandeln Sie das Objekt in eine Zeichenfolge und verketten Sie es. Zauberei, automatische Konvertierungen zwischen nicht verwandten Typen ist nur um Ärger betteln. –