BKahuna
BKahuna

Reputation: 611

Create object of type specified in a string

I have a bunch of classes generated by EF that are simple tables and have similar structures:

public class Contact
{
    public int ID { get; set; }
    public string Description { get; set; }
}

public class Member
{
    public int ID { get; set; }
    public string Description { get; set; }
}

I've also got a method for returning an object of a specified type:

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

What I want to do is something like this:

public ActionResult GetAll(string ClassType)        // ClassType will be the name of one of the classes above
{
    Object LookupType = GetInstance<Object>(ClassType);

    List<LookupType> AllList = new List<LookupType>();

    AllList = repo.GetAll<LookupType>().ToList<LookupType>();    // some generic method that will return a list;
}

This makes the compiler mad because I'm using a variable (LookupType) rather than a true type to build the list. However, neither of these work either:

List<LookupType.GetType()> Items = new List<LookupType.GetType()>();
List<typeof(LookupType)> Items = new List<typeof(LookupType)>();

Both cause an error - "Using generic type List requires 1 type argument".

Is there a proper way to do this? Is there a way to convert ClassType directly to a type without first making it an object (from which I hope to derive the type)?

Upvotes: 1

Views: 175

Answers (3)

Jeffrey Ferreiras
Jeffrey Ferreiras

Reputation: 271

If you don't know the type ahead of time maybe using a list of dynamic objects can help.

    var item = GetInstance<Contact>("Namespace.Contact");
    var items = new List<dynamic>();

    items.Add(item);

You can then access the types like so...

Contact contact = items[0];

Just be aware that using dynamic can be expensive.

Upvotes: 0

Ozzy
Ozzy

Reputation: 303

You cannot do it with C#!! Compiler must to know the parameter type. In that maybe you would like to accomplish, interfaces will help you

public class Contact: IIdDescription
{
        public int ID { get; set; }
        public string Description { get; set; }
}

public class Member: IIdDescription
{
     public int ID { get; set; }
     public string Description { get; set; }
}

public interface IIdDescription
{
     int ID { get; set; }
     string Description { get; set; }
}



public ActionResult GetAll(string type)         
{
   var AllList = new List<IIdDescription>();

   if(type == Member.GetType().Name)
      AllList = repo.Set<Member>().Cast<IIdDescription >().ToList();
   if(type == Contact.GetType().Name)
       AllList = repo.Set<Contact>().Cast<IIdDescription >().ToList();

   ...
}

and into your view use interface as model, something like

 @model IEnumerable<IIdDescription>

Upvotes: 0

Omar Himada
Omar Himada

Reputation: 2588

Try using the CreateInstance method

SomeObject someObject = new SomeObject();
Type type = someObject.GetType();

Type listType = typeof(List<>).MakeGenericType(new [] { type });
IList list = (IList)Activator.CreateInstance(listType);

Upvotes: 1

Related Questions