简体   繁体   English

如何使用System.Type变量调用泛型方法?

[英]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. 我的最终目标实际上是采用两个字符串“ int”和“ 5(作为示例)”,然后将5的值分配给对象[并最终分配给userSettings。]但是我有一种方法可以将“ 5”转换为如果我可以告诉通用方法它是基于字符串表示形式的int类型,则为实际值。

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 . Type.GetType("int")返回null This is invalid because int is just a keyword in the C# language, which is equivalent to the type System.Int32. 这是无效的,因为int只是C#语言中的一个关键字,它等效于System.Int32类型。 It has no special meaning to the .NET CLR, so it's not usable in reflection. 它对.NET CLR没有特殊含义,因此在反射中不可用。 You might have meant typeof(int) or Type.GetType("System.Int32") (or it doesn't really matter, because that was just an example). 您可能已经打算使用typeof(int)Type.GetType("System.Int32") (或者这并不重要,因为那只是示例)。

Anyway, once you have the right Type , this is how you can get your list. 无论如何,一旦您拥有正确的Type ,便可以通过这种方式获取列表。 The key is MakeGenericType . 关键是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: 我将分享杰弗里·里希特(Jeffrey Richter)的《 CLR Via C#》一书中的有关构造泛型类型的示例,这并非特定于该问题,但将帮助您找到合适的方法来完成所需的工作:

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] 将显示:Dictionary`2 [System.String,System.Int32]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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