我的泛型类型是一个列表,还是只是一个项目

本文关键字:一个 项目 列表 我的 泛型类型 | 更新日期: 2023-09-27 18:05:41

我有一个方法,它接受一个泛型参数t。在内部,为了决定调用哪些其他方法,我需要知道(不限制它)该参数是List还是其他东西。

我该怎么做?

我一直在使用

var isList = typeof(T).Name.ToLower().Contains("list`1");

,但这感觉像是一个肮脏的方法。清洁是什么?

我的泛型类型是一个列表,还是只是一个项目

var type = typeof(T);
bool isList = type.IsGenericType && type.GetGenericTypeDefinition() == typeof(List<>);

如果你不需要List的精确匹配,你也可以检查typeof(IList).IsAssignableFrom(typeof(T)),这是许多类似列表的集合实现的。


如果你想支持T直接等于IList<T2>(所以类型参数T是一个接口),那么你需要单独检查(GetGenericTypeDefinition()也可以返回typeof(IList<>))。

如果你想支持从任何IList<>继承的任何类型T,那么你必须更有创意一点。您必须枚举所有接口,检查它们是否为泛型(如上所述),然后检查接口的泛型类型是否为IList<>。另外,由于对Type的GetInterfaces()调用只返回顶级接口,因此您需要浏览每个接口实现的所有接口(递归地),以检查这些接口。丑,我知道。

好吧,你总是可以使用typeof(T)is关键字,但我会再看看你的设计。

你的方法真的违背了泛型方法的目的。如果你必须检查泛型参数的类型,你的方法不是泛型的。泛型适用于不关心底层类型是什么的场景。如果你在意,那么这个方法不应该是泛型的,它应该被重载(很可能)。告诉我们你在这里真正想要完成的是什么,这样我们可以给出更有用的回应,怎么样?

检查是否实现了IEnumerable接口。

bool isList = T is IEnumerable;

如果T是堆栈,数组或其他类似的东西,它也会返回true,但我认为它足以满足您的目的。

如果您正在寻找任何内置集合,您将检查IEnumerable。这样就不需要担心类型参数。然而,这带来了一个问题,因为string实现了IEnumerable。因此,您需要一些像这样的代码:

if (typeof(T) is string) {
} else if (typeof(T) is IEnumerable) {
} else { // its something else
}