0
Type valueType = Type.GetType("int");
object value = new List<valueType>();

The first line compiles fine, But the 2nd does not.

How can I create a generic list (or call a generic method)

object value = foo<valueType>();

By only having a string representation of the type?

My end goal is actually to take two string "int" and "5 (as an example) and assign the value of 5 to the object [and eventually to the userSettings]. But I have a method that will convert "5" to the actual value if I can tell the generic method it is of type int based on the string representation.

T StringToValue<T>(string s)
{
    return (T)Convert.ChangeType(s, typeof(T));
}

Update: I was thinking that creating a generic object and calling a generic method would use the same methodology, but I guess I was wrong. How can I call the generic method?

TruthOf42
  • 2,017
  • 4
  • 23
  • 38
  • My UPDATED question is essentially a duplicate of this question: http://stackoverflow.com/questions/1408120/how-to-call-generic-method-with-a-given-type-object – TruthOf42 Jan 17 '14 at 13:47

3 Answers3

1

Type.GetType("int") returns null. This is invalid because int is just a keyword in the C# language, which is equivalent to the type System.Int32. It has no special meaning to the .NET CLR, so it's not usable in reflection. You might have meant typeof(int) or Type.GetType("System.Int32") (or it doesn't really matter, because that was just an example).

Anyway, once you have the right Type, this is how you can get your list. The key is MakeGenericType.

Type valueType = typeof(int);
object val = Activator.CreateInstance(typeof(List<>).MakeGenericType(valueType));
Console.WriteLine(val.GetType() == typeof(List<int>)); // "True" - it worked!
Tim S.
  • 55,448
  • 7
  • 96
  • 122
0

try this:

Type valueType = Type.GetType("System.Int32");
Type listType = typeof(List<>).MakeGenericType(valueType);
IList list = (IList) Activator.CreateInstance(listType);

// now use Reflection to find the Parse() method on the valueType. This will not be possible for all types
string valueToAdd = "5";
MethodInfo parse = valueType.GetMethod("Parse", BindingFlags.Public | BindingFlags.Static);
object value = parse.Invoke(null, new object[] { valueToAdd });

list.Add(value);
David
  • 625
  • 6
  • 14
  • output list still won't be generic – michalczukm Jan 16 '14 at 21:36
  • That last line won't compile. – H H Jan 16 '14 at 21:36
  • @HenkHolterman: I hopefully fixed the error now (have no access to VS right now) – David Jan 16 '14 at 21:40
  • @michasm: The list is generic. You could cast it into a List if you want to. Since the list type is only given as a string, this can not happen in the code block that generates this class, however if you examine the list object in the debugger you will find it is actually of type List. – David Jan 16 '14 at 21:43
  • This answer will not work because Type.GetType("int") will return null, since the system knows 'int' as System.Int32, so I think the proper way would be Type.GetType("Int32") or Type.GetType("System.Int32"). – David Venegoni Jan 16 '14 at 21:47
  • Creating the list was the easy part. Now show how to add/find data in it. – H H Jan 16 '14 at 21:57
  • @David, the output list still won't be generic. You can cast it but that is not the point. Check this https://gist.github.com/anonymous/8464260 – michalczukm Jan 16 '14 at 21:58
  • @HenkHolterman I added to the example with what should work for the .NET base types. However, I think there is no generic approach to convert a string into an arbitrary type, so this solution is limited. – David Jan 16 '14 at 22:08
0

I will share an example from Jeffrey Richter's book CLR Via C# about constructing generic types, this is not specific to the question but will help guide you to finding the appropriate way of doing what you want:

public static class Program {
     public static void Main() {
       // Get a reference to the generic type's type object
       Type openType = typeof(Dictionary<,>);
       // Close the generic type by using TKey=String, TValue=Int32
       Type closedType = openType.MakeGenericType(typeof(String), typeof(Int32));
      // Construct an instance of the closed type
      Object o = Activator.CreateInstance(closedType);
      // Prove it worked
      Console.WriteLine(o.GetType());
      }
 }

Will display: Dictionary`2[System.String,System.Int32]

David Venegoni
  • 508
  • 3
  • 13