2017-08-15 1 views
-2

BEARBEITEN
Beide Fragen beantworten meine nicht. Vielleicht ein besserer Weg, diese Frage anzugehen:
Wie verwenden Sie eine gegossene Variable als Typ?
ODER Wie verwenden Sie eine Zeichenfolge, die in einen Typ umgewandelt wird, um eine Typvariable zu deklarieren? sieheWie verwenden Sie eine gegossene Variable als Typ?

Beispiel:
Document document = ((document)modelObject);

Der Dokumenttyp wird hier verwendet, aber sagen, dass ich nicht wusste, meine modelObject war ein Dokument, wie würde ich es bekommen?

Hypothetische vorgestellt Lösung, wobei t Dokument

Type t = Type.GetType(type.Name); 
t tVar = ((t)modelObject); 

In meinem Beispiel oben, es funktioniert nicht, weil " 't' eine Variable ist, sondern wie ein Typ verwendet"

ORIGINAL
Ich habe eine Kontrollstruktur, die ich verwenden möchte, um verschiedene Typen zu behandeln, wie sie dynamisch erscheinen. Diese Typen werden mit type.Name erfasst und dann die Steuerungsstruktur basierend auf solchen eingegeben. Ich möchte, dass ich die Kontrollstruktur für Ordner behalten kann, so dass ich die Ordnerfunktionalität weiter bearbeiten kann (die Erweiterung von Ordnern erlauben, etc.), aber verallgemeinere jeden anderen Typ, so dass alle darin behandelt werden können eine einzelne Struktur, anstatt die Struktur immer wieder zu kopieren, aber mit der geringfügigen Änderung des Typs, der gehandhabt werden soll.

Also, meine Strukturen aussehen (grob) wie folgt aus:

Type type = modelObject.GetType(); 
if (type.Name == "Folder") 
{ 
    Folder folder = ((Folder)modelObject); 
    TreeNode NewNode = new TreeNode(folder.Object_string); 

    NewNode.Tag = folder; 

    CurrentRootNode.Nodes.Add(NewNode); 
    if (fRecursive) 
    { 
     ModelObject[] objects = { modelObject }; 
     String[] attributes = { "contents" }; 

     WorkspaceObject[] NewNodeContents = ((Folder)modelObject).Contents; 

     AddContentsToNode(NewNode, NewNodeContents, true); 
    } 
    else 
    { 
     TreeNode EmptyNode = new TreeNode(""); 
     NewNode.Nodes.Add(EmptyNode); 
    } 
} 

if (type.Name == "STL") 
{ 
    STL stl = ((STL)modelObject); 
    TreeNode NewNode = new TreeNode(stl.Object_string); 

    NewNode.Tag = stl; 

    CurrentRootNode.Nodes.Add(NewNode); 
} 

if (type.Name == "Document") 
{ 
    Document document = ((Document)modelObject); 
    TreeNode NewNode = new TreeNode(document.Object_string); 

    NewNode.Tag = document; 

    CurrentRootNode.Nodes.Add(NewNode); 
} 

Beachten Sie, wie die STL und Dokumenttypen behandelt werden genau das gleiche mit dem leichten Variation der Veränderung, welche Art sie wie behandelt werden. Idealerweise würde es so aussehen:

if (type.Name == "Folder") 
{ ... } 
else 
{ 
    (Type)type.Name tn = (((Type)type.Name)modelObject); 
    TreeNode NewNode = new TreeNode(tn.Object_string); 

    NewNode.Tag = tn; 

    CurrentRootNode.Nodes.Add(NewNode); 
} 

jedoch, wie oben zu sehen ist, type.Name eine Zeichenfolge ist.
(Type) type.Name Text auf schweben - Cannot convert type 'string' to 'System.Type'

Die Frage ist also:

Gibt es eine „generische“ Art und Weise Zeichenfolge zu konvertieren zu Typ oder Typ zuweisen auf eine Zeichenfolge basiert?

Ich kann nicht scheinen, irgendeine allgemeine Weise zu finden, die Typdeklaration über die Tafel zu verarbeiten (etwas wie die Idealbeispiel wäre ideal!).

Antwort

0

Während die Umwandlung einer Zeichenkette in einen Typ nicht allzu schwierig ist, muss ich darauf hinweisen, dass Sie dies falsch machen. Sie sollten niemals einen Typ in einer Zeichenfolge speichern müssen, genauso wie Sie niemals eine Zahl in einer Zeichenfolge oder ein Datum in einer Zeichenfolge speichern würden.

Wenn Sie eine Reihe von Typen haben zu prüfen, und verschiedene Aktionen für jeden, folgen diesem Muster:

public void HandleModelObject(object modelObject) 
{ 
    var folder = modelObject as Folder; 
    if (folder != null) 
    { 
     TreeNode NewNode = new TreeNode(folder.Object_string); 
     return; 
    } 
    var document = modelObject as Document; 
    if (document != null) 
    { 
     TreeNode NewNode = new TreeNode(document.Object_string); 
     return; 
    } 
    var someOtherType = modelObject as SomeOtherType; 
    if (someOtherType != null) 
    { 
     TreeNode NewNode = new TreeNode(someOtherType.Object_string); 
     return; 
    } 
} 

Außerdem empfehle ich Ihnen, eine gemeinsame Schnittstelle für alle Objekte hinzufügen, die angezeigt werden können in einem Baumknoten, z IExplorable oder etwas. Dann müssen Sie nicht einmal Stimmen:

interface IExplorable 
{ 
    string Object_string { get; set; } 
} 

class Folder : IExplorable 
{ 
    public string Object_string { get; set; } 
} 

class Document : IExplorable 
{ 
    public string Object_string { get; set; } 
} 

public void HandleModelObject(IExplorable modelObject) 
{ 

    TreeNode NewNode = new TreeNode(modelObject.Object_string); //No if or cast required at all 
} 

Wenn Sie nicht über eine Schnittstelle wollen, und Sie wollen in der Lage sein, jedes Objekt zu handhaben, die nur Eigenschaften, die Sie GetType() und ToString() verwenden können, sind, die sind allen Objekten gemeinsam. Die Lösung ist sehr kurz:

public void HandleModelObject(object modelObject) 
{ 
    TreeNode NewNode = new TreeNode(modelObject.ToString()); 
} 

Wenn Sie nur eine Teilmenge von Objekten zu handhaben müssen, aber sie haben nicht eine gemeinsame Schnittstelle haben, aber sie haben eine gemeinsame Eigenschaft haben (zB string Object_string), dann Sie verwenden könnte bisschen Reflexion. Dies ist ein letzter Ausweg.

public void HandleModelObject(object modelObject) 
{ 
    var value = modelObject.GetType().GetProperty("Object_string", BindingFlags.Instance).GetValue(modelObject) as string; 
    TreeNode NewNode = new TreeNode(value); 
} 

Natürlich werden Sie null Kontrollen müssen, falls Sie versehentlich die falsche Art von Objekt zur Verfügung stellen und es keine Object_string Eigenschaft.

+0

In keinem meiner Beispiele wird etwas instanziiert; Es heißt Cast und ist in Ihrem Beispiel weniger teuer als der String-Vergleich. Aber wenn Sie sie einheitlich bearbeiten wollen (empfohlen), siehe mein zweites Beispiel. –

+0

Das zweite Beispiel erfordert immer noch das Hinzufügen der IExplorable-Schnittstelle zu jeder anderen Option von unzähligen – jtth

+0

Ist das ein Problem? Um welche Art von Objekten geht es hier überhaupt? Sind diese Klassen, die du geschrieben hast? –

0

Sie können die Type.GetType Überladung verwenden, aber Sie sollten die FullName und nicht Name verwenden, da Name zu Mehrdeutigkeit führen kann.

string type = typeof(Program).FullName; 
var typeObj = Type.GetType(type); 

Natürlich gibt dies nur den Klassentyp und nicht die tatsächliche Instanz.

0

Ich konnte meine Zeichenfolgen nicht in Typen konvertieren und sie dann als Typen verwenden. Aus meinen Recherchen ist das nicht möglich. Die Doppelmarkierungen ergaben ebenfalls keine Ergebnisse. Die einzige Problemumgehung, die ich im Moment implementieren konnte, bestand darin, TC-Typen als Knoten direkt ohne Verarbeitungstyp hinzuzufügen.

Verwandte Themen