2010-05-28 20 views
6

Zauważyłem funkcję Object.factory (char [] className) w D. Ale to nie działa tak, jak miałem nadzieję, że to zadziała; to nie działa;)Pobierz instancję klasy według nazwy klasy string

przykład:

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); 
    } 
} 

myślę, że to powinno skutkować komunikatem: „ciąg Zajęcia: TestClass”, ale mówi „nie znaleziono Class”.

Czy ktoś wie, dlaczego tak się dzieje i jak mogę to naprawić?

Czy muszę utworzyć własną fabrykę klas? Na przykład utwórz klasę ze statyczną tablicą Object[string] classes; z instancjami klasy. Gdy chcę nową instancję zrobić to:

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

EDIT:

Używam go teraz tak (przykładem tego jest dla sieci HMVC wzorzec):

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; 
} 

Tego rodzaju rzeczy jest trudne do zrobienia w C++;)

Odpowiedz

6

Oto jeden, który działa:

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); 
    } 
} 

Kilka rzeczy do uwaga:

  1. Trzeba korzystać w pełni kwalifikowaną nazwę klasy. Co jeśli masz więcej niż jedną "TestClass" w swoim programie.
  2. Nie można dołączyć obiektu do łańcucha; musisz użyć toString. To lub po prostu użyj writefln("Class string: %s", i).
+0

A może jeden przeciążenie opCast (T: string) dla klasy, a następnie go sam się konkatenować? – 0scar

+0

Nie, ponieważ i jest typu Object, którego nie można modyfikować. Łatwiej jest // powiedzieć, // co to jest, co próbujesz zrobić: przekształcić obiekt w ciąg i połączyć. Robiąc magię, automatyczne konwersje między niespokrewnionymi typami to tylko błaganie o kłopoty. –

Powiązane problemy