jtth jtth - 1 year ago 51
C# Question

How do you use a casted variable as a Type?

EDIT

Both questions don't answer mine. Perhaps a better way to approach this question:

How do you use a casted variable as a Type?

OR How do you use a string cast to a type to declare a Type variable?

Example, see:

Document document = ((document)modelObject);


The Document type is used here, but say I didn't know my modelObject was a document, how would I obtain it?

Hypothetical imagined solution where t is Document

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


In my example above, it does not work because "'t' is a variable but is used like a type"

ORIGINAL

I have a control structure that I want to use to handle varying types as they appear dynamically. These types are gathered with type.Name and then enter the control structure based on such. What I would like is to be able to do is keep the control structure for folders, so that I can continue handling the folder functionality (allowing the expansion of folders, etc), but generalize each other type so that they can all be handled in a single structure rather then copying the structure over and over but with the slight change of the type to be handled.

So, my structures look (roughly) like this:

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


Notice how the STL and Document types are handled exactly the same with the slight variation of changing what type they are handled as.
Ideally, it would look like this:

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


However, as seen above, type.Name is a string.

(Type)type.Name text on hover -
Cannot convert type 'string' to 'System.Type'


So the question is:

Is there a "generic" way to convert string to Type, or assign Type based on a string?

I can't seem to find any generic way to process the type declaration across the board (something like the Ideally example would be ideal!).

Answer Source

While converting a string to a type is not all that difficult, I have to point out you are going about this the wrong way. You should never have to store a type in a string, just as you would never store a number in a string or a date in a string.

If you have a series of types to check for, and different actions for each, follow this pattern:

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

In addition, I recommend that you add a common interface to all the objects that can appear in a tree node, e.g. IExplorable or something. Then you don't even have to cast:

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
}

If you don't want an interface, and you want to be able to handle any object, the only properties you can use are GetType() and ToString(), which are common to all objects. The solution is very short:

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

If you only need to handle a subset of objects, but they don't have a common interface, but they do have a common property (e.g. string Object_string) then you could use a bit of reflection. This is a last resort.

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

Naturally you will need null checks in case you mistakenly provide the wrong type of object and it doesn't have an Object_string property.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download