簡體   English   中英

是否可以在.net中創建泛型約束類型的集合?

[英]Is it possible to create a collection of generic constrained types in .net?

這樣的事情可能嗎?

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)

支票本質上是不一樣的嗎?

您可以對集合執行運行時強制約束,如下所示:

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>()Remove<T>()方法,您還可以執行以下操作並獲得完全的編譯時類型安全性。

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");
    }
}

檢查不一樣-在第一個示例中,您要求編譯器調用“ IsAssignableFrom”方法,然后根據結果進行操作。 在第二個示例中,您要讓編譯器的靜態類型檢查器做一些工作。

通常,編譯器在編譯期間不會調用任意代碼。

另外,請記住,對泛型的任何類型約束都必須嵌入到程序集元數據中。 同樣,您不能將任意代碼放入通用類型約束中。

無需使用Reflection,就可以實現遵守多種通用約束的事物的集合,但是這非常棘手。 添加到集合中的每個項目都必須用一個類對象包裝。 如果該集合應該保存受I1I2約束的對象,則每個項目都將包裝在類型為TI1I2的泛型類的實例中(約束為T:I1,I2 ),該類實現與泛型的接口類型I1I2 集合本身將保存該接口類型的引用。

如果有人感興趣,我可以發布更多詳細信息。

不,它不可能。 泛型中的Type需要在編譯時解析。

我認為不可能在編譯時進行靜態檢查。 但是您可以覆蓋Add,AddRange和this []在運行時檢查添加的元素。

為此,您需要創建Type(Of TBase)類,然后列出它們。 然后,您可以嘗試確保Type(Of TBase)靜態正確。

但是在大多數情況下,需要從CLR類型創建Type(Of TBase)時,只能動態保證它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM