Определите, имеет ли тип коллекции тип IEnumerable <T>
Как определить, имеет ли объект тип IEnumerable <T> ?
код:
namespace NS {
class Program {
static IEnumerable<int> GetInts() {
yield return 1;
}
static void Main() {
var i = GetInts();
var type = i.GetType();
Console.WriteLine(type.ToString());
}
}
}
Вывод:
NS.1.Program+<GetInts>d__0
Если я изменю GetInts, чтобы вернуть IList, все в порядке
выход:
System.Collections.Generic.List`1[System.Int32]
И это возвращает false:
namespace NS {
class Program {
static IEnumerable<int> GetInts() {
yield return 1;
}
static void Main() {
var i = GetInts();
var type = i.GetType();
Console.WriteLine(type.Equals(typeof(IEnumerable<int>)));
}
}
}
Ответы
Ответ 1
Если вы имеете в виду коллекцию, то просто as
:
var asEnumerable = i as IEnumerable<int>;
if(asEnumerable != null) { ... }
Однако я предполагаю (из примера), что у вас есть Type
:
Объект никогда не будет "из" типа IEnumerable<int>
- но он может его реализовать; Я бы ожидал, что:
if(typeof(IEnumerable<int>).IsAssignableFrom(type)) {...}
. Если вы не знаете T
(int
в приведенном выше), проверьте все реализованные интерфейсы:
static Type GetEnumerableType(Type type) {
foreach (Type intType in type.GetInterfaces()) {
if (intType.IsGenericType
&& intType.GetGenericTypeDefinition() == typeof(IEnumerable<>)) {
return intType.GetGenericArguments()[0];
}
}
return null;
}
и вызовите:
Type t = GetEnumerableType(type);
если это значение равно null, это не IEnumerable<T>
для любого T
- в противном случае проверьте T
.
Ответ 2
Тот же метод, что и у Marc, но Linqier:
namespace NS
{
class Program
{
static IEnumerable<int> GetInts()
{
yield return 1;
}
static void Main()
{
var i = GetInts();
var type = i.GetType();
var isEnumerableOfT = type.GetInterfaces()
.Any(ti => ti.IsGenericType
&& ti.GetGenericTypeDefinition() == typeof(IEnumerable<>));
Console.WriteLine(isEnumerableOfT);
}
}
}
Ответ 3
Так как IEnumerable <T> наследовать IEnumerable (не общий), и если вам не нужно знать, когда тип просто IEnumerable, а не IEnumerable <T> то вы можете использовать:
if (typeof(IEnumerable).IsAssignableFrom(srcType))
Ответ 4
Как определить, имеет ли объект тип IEnumerable <T> ?
Пожалуйста, не стесняйтесь использовать этот прекрасный, сверхмалый универсальный метод расширения, чтобы определить, реализует ли какой-либо объект IEnumerable интерфейс. Он расширяет тип Object, поэтому вы можете выполнить его с помощью любого экземпляра любого объекта, который вы используете.
public static class CollectionTestClass
{
public static Boolean IsEnumerable<T>(this Object testedObject)
{
return (testedObject is IEnumerable<T>);
}
}
Ответ 5
i
имеет тип NS.1.Program+<GetInts>d__0
, который является подтипом IEnumerable<int>
. Таким образом, вы можете использовать
if (i is IEnumerable<int>) { ... }
или IsAssignableFrom
(как в ответе Марка).
Ответ 6
Вы можете использовать ключевое слово is
.
[TestFixture]
class Program
{
static IEnumerable<int> GetInts()
{
yield return 1;
}
[Test]
static void Maasd()
{
var i = GetInts();
Assert.IsTrue(i is IEnumerable<int>);
}
}
Ответ 7
Как определить, является ли тип другим родовым типом, вам следует помочь с этим.