You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
73 lines
1.5 KiB
73 lines
1.5 KiB
using System.Reflection;
|
|
|
|
namespace Connected.Interop
|
|
{
|
|
public static class Enumerables
|
|
{
|
|
public static Type? FindEnumerable(this Type type)
|
|
{
|
|
if (type is null || type == typeof(string))
|
|
return default;
|
|
|
|
if (type.IsArray)
|
|
{
|
|
var elementType = type.GetElementType();
|
|
|
|
if (elementType is not null)
|
|
return typeof(IEnumerable<>).MakeGenericType(elementType);
|
|
else
|
|
return default;
|
|
}
|
|
|
|
var typeInfo = type.GetTypeInfo();
|
|
|
|
if (typeInfo.IsGenericType)
|
|
{
|
|
foreach (var arg in typeInfo.GenericTypeArguments)
|
|
{
|
|
var en = typeof(IEnumerable<>).MakeGenericType(arg);
|
|
|
|
if (en.GetTypeInfo().IsAssignableFrom(typeInfo))
|
|
return en;
|
|
}
|
|
}
|
|
|
|
foreach (var itf in typeInfo.ImplementedInterfaces)
|
|
{
|
|
var en = itf.FindEnumerable();
|
|
|
|
if (en is not null)
|
|
return en;
|
|
}
|
|
|
|
if (typeInfo.BaseType is not null && typeInfo.BaseType != typeof(object))
|
|
return typeInfo.BaseType.FindEnumerable();
|
|
|
|
return default;
|
|
}
|
|
|
|
public static bool IsEnumerable(this Type type)
|
|
{
|
|
return type.FindEnumerable() is not null;
|
|
}
|
|
|
|
public static Type GetEnumerableType(this Type elementType)
|
|
{
|
|
return typeof(IEnumerable<>).MakeGenericType(elementType);
|
|
}
|
|
|
|
public static Type? GetEnumerableElementType(this Type? enumerableType)
|
|
{
|
|
if (enumerableType is null)
|
|
return default;
|
|
|
|
var en = enumerableType.FindEnumerable();
|
|
|
|
if (en is null)
|
|
return enumerableType;
|
|
|
|
return en.GetTypeInfo().GenericTypeArguments[0];
|
|
}
|
|
}
|
|
}
|