Проверьте, является ли IEnumerable <object> IEnumerable <int>

У меня есть переменная типа IEnumerable<object>.

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

Какой лучший способ проверить, если он IEnumerable<int>?

Я пробовал

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

Но Re-Sharper жалуется на все.

В моем случае IEnumerable<object> items имеет тип IEnumerable<int> в большинстве случаев. И я хотел что-то выполнить, когда он имеет тип IEnumerable<int> и что-то еще для других типов.

Ответ 1

Если вы хотите проверить, содержит ли IEnumerable<object> только ints, вы можете использовать Enumerable.All:

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

Ответ 2

Потому что Valuetypes не поддерживают co или контравариантность. IEnumerable<object> не может быть IEnumerable<int> - вы доказали это сами, потому что вам пришлось использовать приведение для создания вашего IEnumerable<object>, на самом деле в котором были помещены все значения int. Таким образом, R # корректно сообщает о подозрительной typecheck, потому что она вытекает из ваших действий, которые ваши проверки всегда будут возвращать false.

Итак, в конце вам нужно будет проверять каждый элемент отдельно, если это int, прежде чем вы будете использовать листинг, или вы столкнетесь с исключением.

Ответ 3

Вы можете использовать Cast или OfType следующим образом:

Просто нужно позаботиться о:

OfType: возвращать только элементы типа x.

В ролях: попытается применить все элементы к типу x. если некоторые из них не относятся к этому типу, вы получите InvalidCastException

items.Cast<int>();

или

items.OfType<int>();

Ответ 4

Вы не можете наложить один родословный на другой, только потому, что тип является базовым классом другого. Таким образом, нет возможности получить Enumerable<int> из Enumerable<object>. Re-Sharper жалуется, потому что выражения не вернутся true.

у вас есть

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

Возможно, вы знаете, что ваше значение A заполнено целыми числами, но вам также разрешено помещать строки и float в ваш items. Поэтому компилятор не может точно знать, что список является перечисляемым из целых чисел.

Итак, вам нужно создать новый перечислимый, как раньше ответил Peyman (который не является новым списком, просто другим перечисляемым):

items.OfType<int>();

это вернет только те элементы, которые являются целыми числами, и гарантирует, что вы можете получить Enumerable<int>