这样的事情可能吗?
Dim l As New List(Of T As Type Where GetType(BaseClass).IsAssignableFrom(T))
注意,我的集合将是类型的集合,而不是T类型的对象 - 我知道这是可能的。
ETA:
到目前为止我得到的答案是预期的 - 我认为不可能。
我想要解决的问题是为什么以下内容可以在编译时解决,但不是我的例子:
Dim l as New List(Of T As BassClass)
检查基本上是否相同?
答案 0 :(得分:2)
您可以对集合实施运行时强制约束,如下所示:
public class ConstrainedTypeCollection<TBaseType> : Collection<Type>
{
protected override void InsertItem(int index, Type item)
{
if (!typeof(TBaseType).IsAssignableFrom(item))
throw new ArgumentException("The type is incompatible.", "item");
base.InsertItem(index, item);
}
protected override void SetItem(int index, Type item)
{
if (!typeof(TBaseType).IsAssignableFrom(item))
throw new ArgumentException("The type is incompatible.", "item");
base.SetItem(index, item);
}
}
修改:只要您调用通用Add<T>()
,Contains<T>()
和{{1},您也可以执行以下操作并获得完整的编译时类型安全性方法。
Remove<T>()
答案 1 :(得分:2)
检查不一样 - 在您的第一个示例中,您要求编译器调用“IsAssignableFrom”方法,然后根据结果执行某些操作。在第二个例子中,您要求编译器的静态类型检查器做一些工作。
通常,编译器在编译期间不会调用任意代码。
另外,请记住,对泛型的任何类型约束都必须嵌入到程序集元数据中。而且,您不能将任意代码放在泛型类型约束中。
答案 2 :(得分:0)
不,不可能。 Type in generic需要在编译时解决。
答案 3 :(得分:0)
我认为在编译时静态检查是不可能的。但您可以覆盖Add,AddRange和this []以在运行时检查添加的元素。
答案 4 :(得分:0)
要做到这一点,你需要创建Type(Of TBase)类,然后列出它们。 然后你可以尝试保证Type(Of TBase)是静态正确的。
但是在大多数情况下,你需要从CLR Type创建Type(Of TBase),它只能动态保证。
答案 5 :(得分:0)
可以在不使用Reflection的情况下实现一系列遵循多个通用约束的东西,但它非常狡猾。添加到集合中的每个项都必须用类对象包装。如果集合应该将事物限制为I1
和I2
,则每个项目都将包含在类型为T
,I1
和{的通用类的实例中{1}}(约束为I2
),它实现了通用类型T:I1,I2
和I1
的接口。集合本身将保存该接口类型的引用。
如果有人有兴趣,我可以发布更多细节。