1

可能重复:
来自字符串值的通用类型

给定一个场景, Class Car: Transport, Class Bus: Transport, Interface Transport,
Get(): Generics Method

有可能做这样的事情吗?

Transport t= Get<"Car">(string color);

public T Get<T>(string color)
{
  return new T(color);
}

P/S:有理由将其动态分配为字符串,而不管返回类型如何。

4

4 回答 4

2

如果您想Get使用字符串,您有两个选择:添加一个Get以 Type 作为参数的非泛型,例如:

public object Get(Type t);

因此您可以传递从字符串创建的类型。第二种选择可能是反射:

MethodInfo method = typeof(YourType).GetMethod("Get");
MethodInfo generic = method.MakeGenericMethod(myType);

然后您可以调用泛型,就好像它已关闭类型 myType。

如果我可以建议使用哪个,并且如果您可以重构该Get方法,我建议添加该方法的非通用版本。如果您确实无法修改库代码,则反射版本有效。正如您可能猜到的那样,使用反射的缺点是性能:您可以决定是否可以继续使用它。

编辑

当然,如果您的方法实际上只是创建最终对象,则我的讨论不适用

在这种情况下,激活器通过传递完整的类型名称来发挥魅力:

Activator.CreateInstance(Type.GetType("yourtypename"));

您通常可以仅基于简单名称(Car、Bus 等)创建类型,因为如果类型不是 ExecutingAssembly,您需要使用命名空间和程序集完全限定。在这种情况下,您必须使用一些约定/配置来简化代码的可读性。

添加

如果您也需要传递参数,我认为您可以尝试开始使用一个简单的IoC(我不会特别推荐一个,选择一个您喜欢的广泛使用的),它可以为您解决所有这些问题。

于 2012-12-29T17:44:00.780 回答
1

如果您在编译类型时不知道类的名称,您将无法使用泛型。你可以使用Activator.CreateInstance

object obj = Activator.CreateInstance(Type.GetType(assemblyQualifiedTypeName));

这假定您正在创建的类型具有默认构造函数。

于 2012-12-29T17:43:34.277 回答
0

使用反射从类型名称中获取对该类型的引用,然后使用它Activator.CreateInstance来创建一个实例。

于 2012-12-29T17:42:00.490 回答
0

不,不是泛型,因为泛型参数需要在编译时解析。

但是,您当然可以将您的类型作为参数中的字符串传递,并让您的方法返回“动态”。

var aCar = Get("Car") as Car;

public dynamic Get(string type)
{
  return Activator.CreateInstance(Type.GetType(type));
}
于 2012-12-29T17:42:49.140 回答