[英]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,就可以實現遵守多種通用約束的事物的集合,但是這非常棘手。 添加到集合中的每個項目都必須用一個類對象包裝。 如果該集合應該保存受I1
和I2
約束的對象,則每個項目都將包裝在類型為T
, I1
和I2
的泛型類的實例中(約束為T:I1,I2
),該類實現與泛型的接口類型I1
和I2
。 集合本身將保存該接口類型的引用。
如果有人感興趣,我可以發布更多詳細信息。
不,它不可能。 泛型中的Type需要在編譯時解析。
我認為不可能在編譯時進行靜態檢查。 但是您可以覆蓋Add,AddRange和this []在運行時檢查添加的元素。
為此,您需要創建Type(Of TBase)類,然后列出它們。 然后,您可以嘗試確保Type(Of TBase)靜態正確。
但是在大多數情況下,需要從CLR類型創建Type(Of TBase)時,只能動態保證它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.