Why can't I create a list <> using myObject?

I created the class dynamically (found it here ), but I do not understand why I can not 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?

+4
source share
6 answers

They are called typical type parameters because they expect types, not instances. Therefore, you need to know the actual type or create a list object with reflection.

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

However, you cannot use this instance in any meaningful way, since it is an object.

  • You can submit it to IList , as suggested in the Avner Shahar-Kashtan answer , and use inorganic methods.

     IList myList = (IList)Activator.CreateInstance(dynamicClassType); 
  • You can also call instance methods of list-instance via reflection.

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

     dynamic myList = Activator.CreateInstance(dynamicClassType); 
+8
source

To build a dynamic type of a generic type, you will need to use Reflection, namely the MakeGenericType method. Something like that:

 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. 

Note that I defined myList as IList , since we do not have a compile time type for it. Fortunately, we have convenient base classes and interfaces, such as IList , IEnumerable and several others that implement List<T> , which we can use.

+6
source

The generic type needs a class type, not an instance, maybe you need:

 var myType = CompileResultType(); var listType = typeof (List<>).MakeGenericType(myType); var myList = Activator.CreateInstance(listType); 

But myList is an object here, if you want to add or remove an item in a list, you must use dynamic :

 dynamic myList = Activator.CreateInstance(listType); 

So you can call:

 myList.Add(...); 
+2
source

this will create a List<WhatEverIsInMyType> :

 var listType = typeof(List<>).MakeGenericType(myType); 

Now you need to create an instance, but you covered it:

 var list = Activator.CreateInstance(listType); 

Unfortunately, we use reflection, so the exact types are not known at compile time, but not everything is lost, you can use non-native types:

  var list = (IList)Activator.CreateInstance(listType); 

Now you can use methods like Add Remove to use your list, but be careful because you will get runtime exceptions if the types don't match the math.

+1
source

Analysis:

The problem is that you are dynamically creating the type and you do not have a compilation type name to refer to it. However, generics require the use of type names.

Say you want a List<string> . string - statically defined type name; you would not declare a variable first, say string foo; and then declare your list as List<foo> ... right?

Like foo , myObject not a type name - it is the name of a variable that refers to an object of your dynamic type - and therefore you cannot use it as a typical type parameter. Similarly, List<myType> also does not work, because myType also not a type name; it is only a variable that refers to a Type object.

Sentence:

If you think about it, using generics here simply will not help, since using generics will not increase the safety of the static type. Use an ArrayList instead.

0
source

You are working with types, not instances. Assuming CompileResultType() returns MyType :

 MyType myType = CompileResultType(); List<MyType> list = new List<MyType>(); 

I'm not sure why you are using Activator.CreateInstance() though ...

0
source

Source: https://habr.com/ru/post/1492872/


All Articles