在运行时使用Type变量创建Type列表

时间:2013-03-13 23:33:05

标签: c# list generics dynamic types

我正在尝试简化我在一个函数中创建几个变量的方法,这个变量针对不同的类型和不同的动作重复,最终我将迁移到一个可以处理多种类型的函数,但我正在分阶段进行。我希望能够在其类型而不是列表中创建对象列表,而无需在任何地方复制/粘贴对象类型。我曾希望通过像

这样简单的事情来实现这一目标
Type t = typeof(LinkAddy);
var x = List<t>();

但这不会编译。

然后我尝试了以下答案提供的另一种解决方案:Storing variable type and using it to create collections at runtime

static IList createGenericList(Type typeInList) {
    var genericListType = typeof(List<>).MakeGenericType(new[] { typeInList });
    return (IList)Activator.CreateInstance(genericListType);
}

static List<T> createGenericList<T>() {
    List<T> genericListType = new List<T>();
    return genericListType;
}

所以这里是不同的方法及其结果:

Type ThisType = typeof(LinkAddy);
// The normal list method, means I have to copy/paste LinkAddy everywhere
var fromQuery = new List<LinkAddy>();
// Makes a List, but I still have to put LinkAddy
var fromQuery_IsNew = createGenericList<LinkAddy>();
// Provides a List, I don't have to place LinkAddy
// but its a List<object> and not List<LinkAddy> so wherever I use
// the objects, I'll have to cast the object like
// string title = (fromQuery_IsDiff[0] as LinkAddy).Title;
var fromQuery_IsDiff = createGenericList(ThisType);

编辑:最后,我不知道运行时的类型,该函数将是通用的,因此我可以将LinkAddy作为类型或其他类型传递,它会根据需要生成列表。第一步是在整个函数中使用泛型,并检查类型是否需要更具体。这是一个大型函数的一部分,它涵盖了大约200行代码,这些代码与数据库同步的列表验证检查有关(它确定哪个缓存和服务器版本更新,哪个更新,如果更新,则覆盖另一个你有权这样做)。我有多个类似于LinkAddy的类,它们使用WCF RIA服务同步,SilverLight同步到服务器上的SQL数据库。这些条目也存储在执行XML序列化的类中,并将XML文件保存到用户的系统(缓存)。这使我在现场的代理可以访问我的大部分网站数据而无需互联网连接,这通常是客户面前的情况。

1 个答案:

答案 0 :(得分:2)

如果您认为这可能会有所作为,并不是很清楚,特别是考虑到评论:

// Provides a List, I don't have to place LinkAddy
// but its a List<object> and not List<LinkAddy> so wherever I use
// the objects, I'll have to cast the object like
// string title = (fromQuery_IsDiff[0] as LinkAddy).Title;

如果你足够了解LinkAddy(最好用作为演员而不是使用as,IMO)那么你在编译时就清楚地知道了这个类型。如果您在编译时知道类型,只需将其作为类型参数提供。

知道编译时涉及的类型时,MakeGenericType之类的内容非常有用,这意味着无法投射...并且你无论如何都不能使用你所知道的任何其他事情。

你可能会使用动态类型......但是如果你知道会有一个Title属性,那么你真正想要的就是一个接口,表达了它的共性。然后,您可能会使用对该接口有约束的泛型方法。

无论如何,你应该考虑在编译时你知道哪些事情以及哪些事情只在执行时才知道。在大多数情况下,泛型是针对编译时已知的类型...虽然通过反射在执行时使用泛型是可能的,但它有点与设计作斗争,所以当它令人沮丧时你不应该感到惊讶。 p>