是否可以在.net中创建泛型约束类型的集合?

是否可以在.net中创建泛型约束类型的集合?,.net,generics,collections,constraints,.net,Generics,Collections,Constraints,这样的事情可能吗 Dim l As New List(Of T As Type Where GetType(BaseClass).IsAssignableFrom(T)) 注意,我的集合将是类型的集合,而不是类型T的对象—我知道这是可能的 预计到达时间: 到目前为止,我得到的答案和预期的一样——我认为这是不可能的 我想弄清楚的是,为什么在编译时可以解决以下问题,但我的示例却不能: Dim l as New List(Of T As BassClass) 检查是否本质上不相同?不,不可能。泛型

这样的事情可能吗

Dim l As New List(Of T As Type Where GetType(BaseClass).IsAssignableFrom(T))
注意,我的集合将是类型的集合,而不是类型T的对象—我知道这是可能的

预计到达时间:

到目前为止,我得到的答案和预期的一样——我认为这是不可能的

我想弄清楚的是,为什么在编译时可以解决以下问题,但我的示例却不能:

Dim l as New List(Of T As BassClass)

检查是否本质上不相同?

不,不可能。泛型中的类型需要在编译时解析。

否不能解析。泛型中的类型需要在编译时解析。

您可以对集合执行运行时强制约束,如下所示:

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);
    }
}
公共类约束类型集合:集合
{
受保护的重写void插入项(int索引,类型项)
{
如果(!typeof(TBaseType).IsAssignableFrom(项目))
抛出新ArgumentException(“类型不兼容。”,“项”);
基本插入项(索引,项目);
}
受保护的覆盖无效集合项(整数索引,类型项)
{
如果(!typeof(TBaseType).IsAssignableFrom(项目))
抛出新ArgumentException(“类型不兼容。”,“项”);
base.SetItem(索引,项);
}
}
编辑:只要调用泛型的
Add()
Contains()
Remove()
方法,您还可以执行以下操作并获得完整的编译时类型安全性

public class ConstrainedTypeCollection<TBaseType> : ICollection<Type>
{
    private readonly List<Type> _collection = new List<Type>();

    public void Add<T>()
        where T : TBaseType
    {
        _collection.Add(typeof(T));
    }

    public bool Contains<T>()
        where T : TBaseType
    {
        return _collection.Contains(typeof(T));
    }

    public bool Remove<T>()
        where T : TBaseType
    {
        return _collection.Remove(typeof(T));
    }

    public int Count
    {
        get
        {
            return _collection.Count;
        }
    }

    bool ICollection<Type>.IsReadOnly
    {
        get
        {
            return false;
        }
    }

    public void Clear()
    {
        _collection.Clear();
    }

    public void CopyTo(Type[] array, int arrayIndex)
    {
        _collection.CopyTo(array, arrayIndex);
    }

    public IEnumerator<Type> GetEnumerator()
    {
        return _collection.GetEnumerator();
    }

    #region ICollection<Type> Members

    void ICollection<Type>.Add(Type item)
    {
        VerifyType(item);
        _collection.Add(item);
    }

    bool ICollection<Type>.Contains(Type item)
    {
        VerifyType(item);
        return _collection.Contains(item);
    }

    bool ICollection<Type>.Remove(Type item)
    {
        VerifyType(item);
        return _collection.Remove(item);
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

    private void VerifyType(Type item)
    {
        if (!typeof(TBaseType).IsAssignableFrom(item))
            throw new ArgumentException("The type is incompatible.", "item");
    }
}
公共类约束类型集合:ICollection
{
私有只读列表_collection=new List();
公共无效添加()
其中T:TBaseType
{
_集合。添加(类型(T));
}
公共布尔包含()
其中T:TBaseType
{
return _collection.Contains(typeof(T));
}
公共布尔删除()
其中T:TBaseType
{
return _collection.Remove(typeof(T));
}
公共整数计数
{
得到
{
返回_collection.Count;
}
}
bool ICollection.IsReadOnly
{
得到
{
返回false;
}
}
公共空间清除()
{
_collection.Clear();
}
public void CopyTo(类型[]数组,int-arrayIndex)
{
_collection.CopyTo(数组、数组索引);
}
公共IEnumerator GetEnumerator()
{
返回_collection.GetEnumerator();
}
#区域i集合成员
作废ICollection.Add(类型项)
{
验证类型(项目);
_集合。添加(项目);
}
bool ICollection.Contains(类型项)
{
验证类型(项目);
返回_集合。包含(项目);
}
布尔ICollection.Remove(类型项)
{
验证类型(项目);
退货_收款。删除(项目);
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
返回GetEnumerator();
}
私有无效验证类型(类型项)
{
如果(!typeof(TBaseType).IsAssignableFrom(项目))
抛出新ArgumentException(“类型不兼容。”,“项”);
}
}
您可以对集合设置运行时强制约束,如下所示:

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);
    }
}
公共类约束类型集合:集合
{
受保护的重写void插入项(int索引,类型项)
{
如果(!typeof(TBaseType).IsAssignableFrom(项目))
抛出新ArgumentException(“类型不兼容。”,“项”);
基本插入项(索引,项目);
}
受保护的覆盖无效集合项(整数索引,类型项)
{
如果(!typeof(TBaseType).IsAssignableFrom(项目))
抛出新ArgumentException(“类型不兼容。”,“项”);
base.SetItem(索引,项);
}
}
编辑:只要调用泛型的
Add()
Contains()
Remove()
方法,您还可以执行以下操作并获得完整的编译时类型安全性

public class ConstrainedTypeCollection<TBaseType> : ICollection<Type>
{
    private readonly List<Type> _collection = new List<Type>();

    public void Add<T>()
        where T : TBaseType
    {
        _collection.Add(typeof(T));
    }

    public bool Contains<T>()
        where T : TBaseType
    {
        return _collection.Contains(typeof(T));
    }

    public bool Remove<T>()
        where T : TBaseType
    {
        return _collection.Remove(typeof(T));
    }

    public int Count
    {
        get
        {
            return _collection.Count;
        }
    }

    bool ICollection<Type>.IsReadOnly
    {
        get
        {
            return false;
        }
    }

    public void Clear()
    {
        _collection.Clear();
    }

    public void CopyTo(Type[] array, int arrayIndex)
    {
        _collection.CopyTo(array, arrayIndex);
    }

    public IEnumerator<Type> GetEnumerator()
    {
        return _collection.GetEnumerator();
    }

    #region ICollection<Type> Members

    void ICollection<Type>.Add(Type item)
    {
        VerifyType(item);
        _collection.Add(item);
    }

    bool ICollection<Type>.Contains(Type item)
    {
        VerifyType(item);
        return _collection.Contains(item);
    }

    bool ICollection<Type>.Remove(Type item)
    {
        VerifyType(item);
        return _collection.Remove(item);
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

    private void VerifyType(Type item)
    {
        if (!typeof(TBaseType).IsAssignableFrom(item))
            throw new ArgumentException("The type is incompatible.", "item");
    }
}
公共类约束类型集合:ICollection
{
私有只读列表_collection=new List();
公共无效添加()
其中T:TBaseType
{
_集合。添加(类型(T));
}
公共布尔包含()
其中T:TBaseType
{
return _collection.Contains(typeof(T));
}
公共布尔删除()
其中T:TBaseType
{
return _collection.Remove(typeof(T));
}
公共整数计数
{
得到
{
返回_collection.Count;
}
}
bool ICollection.IsReadOnly
{
得到
{
返回false;
}
}
公共空间清除()
{
_collection.Clear();
}
public void CopyTo(类型[]数组,int-arrayIndex)
{
_collection.CopyTo(数组、数组索引);
}
公共IEnumerator GetEnumerator()
{
返回_collection.GetEnumerator();
}
#区域i集合成员
作废ICollection.Add(类型项)
{
验证类型(项目);
_集合。添加(项目);
}
bool ICollection.Contains(类型项)
{
验证类型(项目);
返回_集合。包含(项目);
}
布尔ICollection.Remove(类型项)
{
验证类型(项目);
退货_收款。删除(项目);
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
返回GetEnumerator();
}
私有无效验证类型(类型项)
{
如果(!typeof(TBaseType).IsAssignableFrom(项目))
抛出新ArgumentException(“类型不兼容。”,“项”);
}
}

我认为不可能在编译时对其进行静态检查。但是您可以重写Add、AddRange和this[],以便在运行时检查添加的元素。

我认为不可能在编译时静态检查这些元素。但是您可以重写Add、AddRange和this[]以在运行时检查添加的元素。

检查不一样-在第一个示例中,您要求编译器调用“IsAssignableFrom”