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.
Connected.Framework/Connected.Interop/Enumerables.cs

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];
}
}
}