確定泛型型別例項的泛型引數
如果你有泛型型別的例項但由於某種原因不知道特定型別,則可能需要確定用於建立此例項的泛型引數。
假設某人建立了 List<T>
的例項,並將其傳遞給方法:
var myList = new List<int>();
ShowGenericArguments(myList);
ShowGenericArguments
有這個簽名:
public void ShowGenericArguments(object o)
所以在編譯時你不知道使用了什麼泛型引數來建立 o
。 Reflection 提供了許多檢查泛型型別的方法。首先,我們可以確定 o
的型別是否是泛型型別:
public void ShowGenericArguments(object o)
{
if (o == null) return;
Type t = o.GetType();
if (!t.IsGenericType) return;
...
如果型別是泛型型別,則 Type.IsGenericType
返回 true
,如果不是,則返回 false
。
但這不是我們想知道的全部。List<>
本身也是一種通用型別。但我們只想檢查特定構造泛型型別的例項。構造的泛型型別是例如具有特定型別 List<int>
引數用於其所有的通用引數。
Type
類提供了另外兩個屬性 IsConstructedGenericType
和 IsGenericTypeDefinition
,以區分這些構造的泛型型別和泛型型別定義:
typeof(List<>).IsGenericType // true
typeof(List<>).IsGenericTypeDefinition // true
typeof(List<>).IsConstructedGenericType// false
typeof(List<int>).IsGenericType // true
typeof(List<int>).IsGenericTypeDefinition // false
typeof(List<int>).IsConstructedGenericType// true
要列舉例項的泛型引數,我們可以使用 GetGenericArguments()
方法返回包含泛型型別引數的 Type
陣列:
public void ShowGenericArguments(object o)
{
if (o == null) return;
Type t = o.GetType();
if (!t.IsConstructedGenericType) return;
foreach(Type genericTypeArgument in t.GetGenericArguments())
Console.WriteLine(genericTypeArgument.Name);
}
所以上面的呼叫(ShowGenericArguments(myList)
)會產生這樣的輸出:
Int32