Check if IEnumerable<object> is IEnumerable<int>

本文关键字:gt lt IEnumerable int is object Check if | 更新日期: 2023-09-27 17:50:53

我有IEnumerable<object>类型变量

IEnumerable<object> items= new object[] { 1, 2, 3 };

检查是否为IEnumerable<int>的最佳方法是什么?

I tried

typeof(IEnumerable<int>).IsAssignableFrom(items.GetType())
typeof(IEnumerable<int>).IsInstanceOfType(items)
items is IEnumerable<int>

但是,Re-Sharper抱怨他们所有人。

在我的例子中,IEnumerable<object> items大多数情况下为IEnumerable<int>类型。我想对IEnumerable<int>类型执行一些操作而对其他类型执行一些操作

Check if IEnumerable<object> is IEnumerable<int>

如果你想检查IEnumerable<object>是否只包含整数,你可以使用Enumerable.All:

var isInts = items.All(x => x is int);

因为Valuetypes不支持co或逆变。IEnumerable<object>不可能是IEnumerable<int>——你自己证明了这一点,因为你必须使用强制转换来产生IEnumerable<object>,它实际上对所有int值进行了装箱。因此,r#正确地报告了可疑的类型检查,因为它派生自您的操作,您的检查将始终返回false。

因此,在使用强制类型转换之前,您需要单独检查每个元素是否为int,否则您将遇到异常。

您可以像这样使用Cast或OfType:

Just should care of:

OfType:只返回x类型的元素。

Cast:将尝试将所有元素强制转换为x类型,如果其中一些不是来自此类型,您将得到InvalidCastException

items.Cast<int>();

items.OfType<int>();

不能仅仅因为一个泛型是另一个泛型的基类而将其强制转换为另一个泛型。所以没有机会从Enumerable<object>中得到Enumerable<int>。Re-Sharper抱怨,因为表达式永远不会返回true。

你有

IEnumerable<object> items= ((IEnumerable)valueA).Cast<object>();

也许你知道你的valueA是由整数填充的,但是你也可以在你的items中放置字符串或浮点数。因此,编译器不能确定该列表是一个可枚举的整数。

所以你必须创建一个新的可枚举对象,就像Peyman之前回答的那样(这不是一个新列表,只是另一个可枚举对象):
items.OfType<int>();

这将只返回整数元素,并确保您可以获得Enumerable<int>