Beta033
Beta033

Reputation: 2013

dynamically creating objects from string to derived types

What i'm tring to do is this.

I have a Inheritance tree that looks something like this

BaseType
BaseType : DerType1
BaseType : DerType2
BaseType : DerType3

so first i've declare a variable of type BaseType to be used

BaseType b;

Any of the derived types can be read in as a string

so i've got an instance creator something like

  object o =  Activator.CreateInstance(Type.GetType(readValue));

What i then want to do is assign this new object to B

Something like

b = o //Doesn't work obviously because of casting rules
b= (DerType1)o; //works 

but i can't figure out how to dynamically retype the intended cast

b = (o.GetType())o; //what i want but can't be done like this

maybe there's a trick with using generics i'm not thinking about?

I found an article talking about doing it something like this with generics

public T GetInstance<T>(string type) where T: new()
        {
            return (T)Activator.CreateInstance(Type.GetType(typeName));
        } 

but it seems to me that i still will need to statically reference the type name in the call to this method

b  = GetInstance<DerType1>("DerType1")
b  = GetInstance<DerType2>("DerType2")
b  = GetInstance<DerType3>("DerType3")

thanks for the ideas.

Maybe i should be taking a whole new, better approach? Also maybe i'm just not paying attention as

b = (BaseType)Activator.CreateInstance(Type.GetType(typeName));

seems to be helpful

Upvotes: 0

Views: 331

Answers (3)

Justin Niessner
Justin Niessner

Reputation: 245399

I would suggest creating a Factory for your types (and casting everything to the BaseType since that's the type you're really going to be using anyway):

public static BaseTypeFactory
{
    public enum Types { DerType1, DerType2, DerType3 }

    public static BaseType CreateInstance(Types type)
    { 
        switch(type)
        {
            case Types.DerType1:
                return (BaseType) Activator.
                    CreateInstance(Type.GetType("DerType1"));
            case Types.DerType2:
                return (BaseType) Activator.
                    CreateInstance(Type.GetType("DerType2"));
            case Types.DerType3:
                return (BaseType) Activator.
                    CreateInstance(Type.GetType("DerType3"));
            default:
                thrown new ArgumentException("Invalid Type specified");
        }
    }
}

Upvotes: 0

dcp
dcp

Reputation: 55424

Why not just declare:

object o;

as

BaseType o;

Then you could do:

BaseType o =  Activator.CreateInstance(Type.GetType(readValue)) as BaseType;

Upvotes: 1

LBushkin
LBushkin

Reputation: 131666

Don't cast to the derived types if you aren't doing anything with them. Just cast to BaseType:

BaseType b = (BaseType)Activator.CreateInstance(Type.GetType(readValue)); 

You only need to cast to a type more specific than BaseType if you are going to write code that relies on members of that derived type. If you are going to treat all derived types polymorphically, just cast to the base type.

Casts within a type hierarchy don't change the type of object you referencing ... they just perform a quick runtime check (to make sure the reference is really of that type) and then reinterpret the reference.

Upvotes: 2

Related Questions