.NET Reflection: обнаружение IEnumerable <T>
Я пытаюсь определить, является ли конкретный экземпляр объекта Type общим "IEnumerable"...
Лучшее, что я могу придумать, это:
// theType might be typeof(IEnumerable<string>) for example... or it might not
bool isGenericEnumerable = theType.GetGenericTypeDefinition() == typeof(IEnumerable<object>).GetGenericTypeDefinition()
if(isGenericEnumerable)
{
Type enumType = theType.GetGenericArguments()[0];
etc. ...// enumType is now typeof(string)
Но это кажется немного косвенным - есть ли более прямой/элегантный способ сделать это?
Ответы
Ответ 1
Вы можете использовать
if(theType.IsGenericType && theType.GetGenericTypeDefinition() == typeof(IEnumerable<>))
{
Type underlyingType = theType.GetGenericArguments()[0];
//do something here
}
EDIT: добавлена проверка IsGenericType, спасибо за полезные комментарии
Ответ 2
Вы можете использовать этот фрагмент кода, чтобы определить, реализует ли конкретный тип интерфейс IEnumerable<T>
.
Type type = typeof(ICollection<string>);
bool isEnumerable = type.GetInterfaces() // Get all interfaces.
.Where(i => i.IsGenericType) // Filter to only generic.
.Select(i => i.GetGenericTypeDefinition()) // Get their generic def.
.Where(i => i == typeof(IEnumerable<>)) // Get those which match.
.Count() > 0;
Он будет работать для любого интерфейса, однако он будет не работать, если тип, который вы проходите, IEnumerable<T>
.
Вы должны иметь возможность изменить его, чтобы проверить аргументы типа, переданные каждому интерфейсу.
Ответ 3
Обратите внимание, что вы не можете вызвать GetGenericTypeDefinition()
для не общего типа, поэтому сначала проверьте с помощью IsGenericType
.
Я не уверен, хотите ли вы проверить, реализует ли тип общий IEnumerable<>
, или если вы хотите видеть, имеет ли тип интерфейса IEnumerable<>
. В первом случае используйте следующий код (внутренняя проверка с interfaceType
- это второй случай):
if (typeof(IEnumerable).IsAssignableFrom(type)) {
foreach (Type interfaceType in type.GetInterfaces()) {
if (interfaceType.IsGenericType && (interfaceType.GetGenericTypeDefinition() == typeof(IEnumerable<>))) {
Console.WriteLine("{0} implements {1} enumerator", type.FullName, interfaceType.FullName); // is a match
}
}
}