假设我有一个对象,它 * 可能 * 是IEnumerable<T>
类型。我想写一个方法,如果对象的类型是IEnumerable<T>
,则返回true,不为null,也不为空。
这是我目前得到的:
public bool IsNullOrEmpty(object obj)
{
if (obj != null)
{
if (obj is IEnumerable<object>)
{
return (obj as IEnumerable<object>).Any();
}
}
return false;
}
如果我传入一个List<string>
类型的对象,这将有效,但如果我传入一个List<int>
类型的对象,则无效。因为obj is IEnumerable<object>
返回false
。
任何想法,我如何才能使这对所有通用的IEnumerable
的工作?
7条答案
按热度按时间u5rb5r591#
由于类型可能未知,您可以尝试检查
IEnumerable
接口并在枚举器上使用MoveNext()
。**编辑:**我更新了方法名称。现在逻辑更有意义了,因为最初的问题代码是检查集合中是否有项目。
a8jjtwal2#
System.Collections.Generic.IEnumerable<T>
继承自System.Collections.IEnumerable
-因此,如果您可以检查非泛型IEnumerable
,而不是泛型IEnumerable<T>
,则可以直接转换为IEnumerable
。关于你的代码的几点注意事项:首先检查
is
,然后转换为as
。这通常是不必要的;as
已经检查并在转换失败时返回null
。因此,更短的方法是:请注意,您将需要对
Cast
的额外调用,因为Any
需要一个泛型IEnumerable<T>
。o4tp2gmn3#
你可以尝试将其转换为
IEnumerable
:...
顺便说一句,有趣的是,它可以正确地使用空字符串:
62lalag44#
您可以检查非泛型
IEnumerable
并检查其是否为空。您可以添加一个检查,以确保对象使用反射实现IEnumerable<T>
:dluptydi5#
为了完整起见,添加最新c#版本(从c#8.0开始)的最新答案:
这假设您知道调用站点中的
T
。如果你不知道
T
,你不应该使用IEnumerable<object>
,而应该使用IEnumerable
。大概是这样的:vcirk6k66#
你可以先检查对象是否像列表和数组一样实现了
ICollection
,因为检查其中一个的大小更便宜,因为它们有Count
属性。如果不是,你可以检查它是否实现了IEnumerable
,如果实现了,创建一个枚举器,看看你是否可以移动到第一项:icomxhvb7#
这个答案将问题扩展到了
IEnumerable<T>
范围之外,即“我拥有的这个东西可以在foreach
-loop中使用吗?”“.您可能知道,
foreach
主要不检查IEnumerable
,而是尝试枚举给定的任何内容。这将适用于所有类型,在某种意义上,
foreach
认为:这基本上和
foreach
-loop做的是一样的,即检查可枚举性,并没有真正给予一个关于所涉及类型的该死的东西。因此,它真的应该避免,但如果你以某种方式必须检查,如果你可以把你的类型在
foreach
-循环,这应该做的伎俩。