Информация об изменениях

Сообщение Re: Сравнение System.Type от 09.09.2016 12:47

Изменено 09.09.2016 13:02 Serginio1

IEnumerable<>);Здравствуйте, vorona, Вы писали:

V>Почему сравнение по типу возвращает false, а по токену true;

V>
V>MethodInfo openMethod = typeof(Enumerable).GetMethods().First(m => m.Name == nameof(Enumerable.Select));
V>bool type = openMethod.ReturnType == typeof(IEnumerable<>);
V>bool token = openMethod.ReturnType.MetadataToken == typeof(IEnumerable<>).MetadataToken;
V>


Вообще openMethod.ReturnType <> typeof(IEnumerable<>);
Так как он выведен из typeof(IEnumerable<>) ParameterType.IsConstructedGenericType

Правильно будет
openMethod.ReturnType.GetGenericTypeDefinition() == typeof(IEnumerable<>)


А вообще вот функция
  public static bool IsGenericTypeOf(this Type t, TypeInfo TI, Type genericDefinition)
        {
            Type InterfaceType;
            return IsGenericTypeOf(t, genericDefinition, TI, out InterfaceType);

        }
        public static bool IsGenericTypeOf(this Type t, Type genericDefinition, TypeInfo TI, out Type InterfaceType)
        {
            InterfaceType = null;
            if (t == null) return false;



            if (t.GetTypeInfo().IsGenericType && t.GetGenericTypeDefinition() == genericDefinition.GetGenericTypeDefinition()) return true;

            if (t.GetTypeInfo().BaseType != null)
            {
                var BT = t.GetTypeInfo().BaseType;
                if (BT != null && BT.IsGenericTypeOf(genericDefinition, TI, out InterfaceType))
                {
                    if (InterfaceType == null) InterfaceType = BT;
                    return true;
                }
            }

            if (TI.IsInterface)
            {

                foreach (var i in t.GetTypeInfo().GetInterfaces())
                {
                    if (i.IsGenericTypeOf(genericDefinition, TI, out InterfaceType))
                    {
                        if (InterfaceType == null) InterfaceType = i;
                        return true;

                    }
                }
            }


            return false;
        }



Вот поиск типов расширений Linq


static Type[] ПолучитьТипыРасширенийLinq()
        {
            var ТипПеречислителя = typeof(IEnumerable<>);
            var assembly = (typeof(System.Linq.Enumerable)).GetTypeInfo().Assembly;
            var query = from type in assembly.GetTypes()
                        let TI = type.GetTypeInfo()
                        where TI.IsSealed && TI.IsAbstract
                        from method in TI.GetMethods()
                        where method.IsStatic && method.IsDefined(typeof(System.Runtime.CompilerServices.ExtensionAttribute), false) && method.IsGenericMethod
                        let ParameterType = method.GetParameters()[0].ParameterType
                        where ParameterType.IsConstructedGenericType && ParameterType.GetGenericTypeDefinition() == ТипПеречислителя

                        select type;


            return query.Distinct().ToArray();
        }
IEnumerable<>);Здравствуйте, vorona, Вы писали:

V>Почему сравнение по типу возвращает false, а по токену true;

V>
V>MethodInfo openMethod = typeof(Enumerable).GetMethods().First(m => m.Name == nameof(Enumerable.Select));
V>bool type = openMethod.ReturnType == typeof(IEnumerable<>);
V>bool token = openMethod.ReturnType.MetadataToken == typeof(IEnumerable<>).MetadataToken;
V>


Вообще openMethod.ReturnType <> typeof(IEnumerable<>);
Так как он выведен из IEnumerable<> и ParameterType.IsConstructedGenericType возвращает истина

Правильно будет
openMethod.ReturnType.GetGenericTypeDefinition() == typeof(IEnumerable<>)


А вообще вот функция
  public static bool IsGenericTypeOf(this Type t, TypeInfo TI, Type genericDefinition)
        {
            Type InterfaceType;
            return IsGenericTypeOf(t, genericDefinition, TI, out InterfaceType);

        }
        public static bool IsGenericTypeOf(this Type t, Type genericDefinition, TypeInfo TI, out Type InterfaceType)
        {
            InterfaceType = null;
            if (t == null) return false;



            if (t.GetTypeInfo().IsGenericType && t.GetGenericTypeDefinition() == genericDefinition.GetGenericTypeDefinition()) return true;

            if (t.GetTypeInfo().BaseType != null)
            {
                var BT = t.GetTypeInfo().BaseType;
                if (BT != null && BT.IsGenericTypeOf(genericDefinition, TI, out InterfaceType))
                {
                    if (InterfaceType == null) InterfaceType = BT;
                    return true;
                }
            }

            if (TI.IsInterface)
            {

                foreach (var i in t.GetTypeInfo().GetInterfaces())
                {
                    if (i.IsGenericTypeOf(genericDefinition, TI, out InterfaceType))
                    {
                        if (InterfaceType == null) InterfaceType = i;
                        return true;

                    }
                }
            }


            return false;
        }



Вот поиск типов расширений Linq


static Type[] ПолучитьТипыРасширенийLinq()
        {
            var ТипПеречислителя = typeof(IEnumerable<>);
            var assembly = (typeof(System.Linq.Enumerable)).GetTypeInfo().Assembly;
            var query = from type in assembly.GetTypes()
                        let TI = type.GetTypeInfo()
                        where TI.IsSealed && TI.IsAbstract
                        from method in TI.GetMethods()
                        where method.IsStatic && method.IsDefined(typeof(System.Runtime.CompilerServices.ExtensionAttribute), false) && method.IsGenericMethod
                        let ParameterType = method.GetParameters()[0].ParameterType
                        where ParameterType.IsConstructedGenericType && ParameterType.GetGenericTypeDefinition() == ТипПеречислителя

                        select type;


            return query.Distinct().ToArray();
        }