是否可以在设计时不知道类型的情况下声明泛型的实例?
示例:
Int i = 1;
List<typeof(i)> list = new List<typeof(i)>();
其中i的类型可以是任何东西,而不是必须:
List<int> list = new List<int();
答案 0 :(得分:46)
如果您在编译时不知道类型,但是您想要实际类型(即不是List<object>
)和,那么您不在通用方法/类型中适当的类型参数,然后你必须使用反射。
为了使反射更简单,我有时会在我自己的代码中引入一个新的泛型类型或方法,所以我可以通过反射调用它,但之后只需使用普通的泛型。例如:
object x = GetObjectFromSomewhere();
// I want to create a List<?> containing the existing
// object, but strongly typed to the "right" type depending
// on the type of the value of x
MethodInfo method = GetType().GetMethod("BuildListHelper");
method = method.MakeGenericMethod(new Type[] { x.GetType() });
object list = method.Invoke(this, new object[] { x });
// Later
public IList<T> BuildListHelper<T>(T item)
{
List<T> list = new List<T>();
list.Add(item);
return list;
}
当然,如果你不知道这种类型,你就不能对这个列表做很多事情......这就是为什么这种事情常常会失败的原因。并非总是如此 - 我曾经在一些场合使用了类似上面的东西,其中类型系统并不能让我静态地表达我需要的一切。
编辑:请注意,虽然我在上面的代码中调用了Type.GetMethod,如果你要执行它很多,你可能只想调用一次 - 毕竟,该方法不会更改。您可以将其设置为静态(您可以在上面的情况下)并且您可能也希望将其设为私有。我将其作为公共实例方法保留,以简化示例代码中的GetMethod调用 - 否则您需要指定适当的绑定标志。
答案 1 :(得分:1)
我认为你能做的最好的事情就是这样:
static void Main(string[] args)
{
int i = 1;
var thelist = CreateList(i);
}
public static List<T> CreateList<T>(T t)
{
return new List<T>();
}
答案 2 :(得分:1)
如果你在设计时不知道类型,我会说你有一个OBJECTS列表(所有其他类型的基类)。
List<object> list = new List<object>();
答案 3 :(得分:1)
您还可以使用Activator.CreateInstance。示例代码段:
public class BaseRepository<T> where T : DataContext
{
protected T _dc;
public BaseRepository(string connectionString)
{
_dc = (T) Activator.CreateInstance(typeof(T), connectionString);
}
public void SubmitChanges()
{
_dc.SubmitChanges();
}
}
答案 4 :(得分:0)
非常确定你能做到这一点,它们不必像编译模板一样在编译时修复。
此处类似的示例:http://geekswithblogs.net/marcel/archive/2007/03/24/109722.aspx
答案 5 :(得分:0)
查看类似问题"Dynamically Create a Generic Type for Template"的答案。唯一的区别是他们从命令行生成类型,其余的你应该能够适应你的需求。
顺便说一下,你不能在实例上调用typeof - 获取实例的类型(例如“i”调用GetType():
Type intType = i.GetType();
答案 6 :(得分:0)
如果您仍想输入.Add(),. Remove(),请执行foreach等操作,您可以将List视为常规的“旧”System.Collections.IList, 因为这个界面幸运地由List&lt; T&gt;实现。
由于此问题的所有其他发布的答案几乎都显示了创建List&lt; T&gt;的实例的所有其他可能方式。动态, 我将展示最后一种方法。 我个人在创建泛型实例时使用此方法,当我在编译时对类型一无所知时, 并且类型必须作为字符串传递,可能来自应用程序配置文件。 在这个例子中,为简单起见,T是System.String,但它可以是任何东西:
Type T = typeof ( string ); // replace with actual T
string typeName = string.Format (
"System.Collections.Generic.List`1[[{0}]], mscorlib", T.AssemblyQualifiedName );
IList list = Activator.CreateInstance ( Type.GetType ( typeName ) )
as IList;
System.Diagnostics.Debug.Assert ( list != null ); //
list.Add ( "string 1" ); // new T
list.Add ( "string 2" ); // new T
foreach ( object item in list )
{
Console.WriteLine ( "item: {0}", item );
}