简体   繁体   中英

How do I use System.Type variable to call a generic method?

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?

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!

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);

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]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM