【发布时间】:2011-01-30 23:38:18
【问题描述】:
问题:
是否有一种静态方法可以使用 Reflection 或 Microsoft.Cci 可靠地确定派生自 CollectionBase 的类型所包含的类型?
背景:
我正在开发一个代码生成器,它可以复制类型、制作这些类型的自定义版本以及在它们之间进行转换器。它通过 Microsoft.Cci 遍历源程序集中的类型。它使用文本模板打印出源代码。它进行了大量的转换和自定义,并丢弃了我不关心的代码。
在生成的代码中,我打算在之前使用 CollectionBase、IEnumerable<T> 或 T[] 的任何地方替换 List<T>。我想使用List<T>,因为我很确定我可以在没有额外工作的情况下对其进行序列化,这对我的应用程序很重要。 T 在任何情况下都是具体的。我试图不复制 CollectionBase 类,因为我必须复制自定义实现,并且我想避免在我的代码生成器中这样做。
我唯一遇到问题的部分是在替换自定义 CollectionBase 时为 List<T> 确定 T。
到目前为止我做了什么:
我已经简要查看了 CollectionBase 的 MSDN 文档和示例,他们提到在派生类型上创建自定义 Add 方法。我不认为这是以任何方式强制执行的,所以我不确定我是否可以依赖它。实现者可以将其命名为其他名称,或者更糟的是,拥有一个支持多种类型的集合,Object 作为它们唯一的共同祖先。
我考虑过的替代方案:
也许默认的序列化做了一些我可以利用的技巧。 CollectionBase 集合是否有默认序列化,或者您通常必须自己实现它?如果您必须自己做,是否有一些可靠的元数据我可以查看以确定类型?如果它支持默认序列化,它是否依赖于集合中项目的运行时类型?
我可以在我的代码生成器中对已知的CollectionBase 类型进行映射,映射到它们对应的T 以获取List<T>。如果我遇到的给定 CollectionBase 类型不在列表中,则抛出异常。如果没有可靠的替代方案,我可能会采用这种方式。
【问题讨论】:
-
为什么
CollectionBase在这里相关?另外,您的目标是哪个版本的 Visual Studio?有关 VS2008 的Cci命名空间如何更改,请参阅 msdn.microsoft.com/en-us/library/cc901387(VS.90).aspx。 -
@John:我的目标是 3.5。我正在使用 codeplex 的公共 2.0-ish 源代码。
CollectionBase是相关的,因为源代码具有派生自它的类型,我希望我的目标代码更改这些属性和方法以使用List<T>。我已经编辑了我的问题,所以希望重要的细节现在更清楚:) -
@Merlyn:你关心什么样的序列化?我没有发现需要您更改
CollectionBase的问题。 -
@John:我要的解决方案不是解决序列化问题(尽管序列化是必需的),而是解决依赖问题。我正在尝试从现有的单体代码库中递归地克隆一组服务,以便我可以尽可能地删除对它的依赖。我正在创建接口,并递归地制作类似行为的 DTO。目标接口是 ASMX Web 服务,它们没有用于接口/DTO 的干净独立库。我无法签入对该代码库的更改,但预计更改将来自其他来源,因此是代码生成器。
-
@John:有没有办法让多个服务引用生成共享基类型(不重用现有的),然后使用
partial自定义它们?那也可以解决我的问题:)
标签: reflection cci collectionbase