Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why I cannot create a List<> using myObject?

Tags:

c#

I created a class dynamically (found it here) but I don't understand why I cannot use it to create a list?

var myType = CompileResultType();
var myObject = Activator.CreateInstance(myType);
var myList = new List<myObject>();

// Error: The type or namespace name 'myObject' 
// could not be found (are you missing a using directive 
// or an assembly reference?)

How should I do it?

like image 259
yonan2236 Avatar asked Dec 03 '22 22:12

yonan2236


2 Answers

They're called generic type parameters, because they expect types, not instances. So you need to know the actual type or create the list object with reflection as well.

Type listType = typeof(List<>);
Type dynamicClassType = listType.MakeGenericType(myObject.GetType());
object myList = Activator.CreateInstance(dynamicClassType);

However, you're unable to use the instance in any meaningful way since it's an object.

  • You could cast it to an IList as suggested in Avner Shahar-Kashtan's answer and use the nongeneric methods.

    IList myList = (IList)Activator.CreateInstance(dynamicClassType);
    
  • You could call the methods of the list-instance through reflection as well.

    // roughly
    MethodInfo addMethod = myList.GetType().GetMethod("Add");
    addMethod.Invoke(myList, objectToAdd);
    
  • Or do as suggested in Cuong Le's answer and use dynamic as the type of the list-instance.

    dynamic myList = Activator.CreateInstance(dynamicClassType);
    
like image 100
J. Steen Avatar answered Dec 05 '22 10:12

J. Steen


In order to construct a generic type dynamically, you'll have to use Reflection, and specifically the MakeGenericType method. Something like this:

Type baseListType = typeof(List<>); // get the generic List<>
Type myType = CompileResultType; // same as in yours.
Type myListType = baseListType.MakeGenericType(myType); // Get the List<MyType>
IList myList = (IList)Activator.CreateInstance(myListType); // Instantiate.

Notice that I defined myList as IList, since we don't have a compile-time type for it. Luckily, we have convenient base classes and interfaces like IList, IEnumerable and several others that List<T> implements, which we can use.

like image 26
Avner Shahar-Kashtan Avatar answered Dec 05 '22 10:12

Avner Shahar-Kashtan