Home > Enterprise >  MakeGenericMethod For Max Is Not Working In .Net 6
MakeGenericMethod For Max Is Not Working In .Net 6

Time:11-05

So we recently migrated our project from .net framework 4.7.2 to .net 6 and we are testing the code for any issues , while testing i found out that the following method for Max is not working in .net 6

var maxOfStringMethod = (from method in typeof(Enumerable).GetMethods()
                                   where method.Name == "Max"
                        && method.GetParameters().Length == 2 &&
                        method.GetParameters()[1].ParameterType.GenericTypeArguments[1].IsGenericParameter
                                   select method).First().MakeGenericMethod(new Type[] { typeof(SomeViewModel), typeof(string) });

Above code method is for "TResult Max[TSource,TResult](System.Collections.Generic.IEnumerable1[TSource], System.Func2[TSource,TResult])".
It was working fine in .net framework 4.7.2 , but while testing the migrated code in .net 6 it throws "ArrayOutOfBoundsException" So i tried changing the above code to following for getting same result from Enumerable methods in .Net 6

  var maxOfStringMethod = (from method in typeof(Enumerable).GetMethods()
                where method.Name == "Max"
                      && method.GetParameters().Length == 2 &&
                      method.GetParameters()[0].ParameterType.GenericTypeArguments[0].IsGenericParameter
                select method).ElementAt(1).MakeGenericMethod(new Type[] { typeof(SomeViewModel), typeof(string) });

Now it's throwing "System.ArgumentException: 'The type or method has 1 generic parameter(s), but 2 generic argument(s) were provided. A generic argument must be provided for each generic parameter.' " I dont know what to do to solve this next , any help will be much appreciated

CodePudding user response:

To prevent new or removed overloads to break your code you can pin down the required overload much more. Also this code is independent of the method order and will yield the required overload or throw an exception:

var maxOfStringMethod = typeof(Enumerable).GetMethods()
    .Single(x => x.Name == nameof(Enumerable.Max)
            && x.GetGenericArguments().Length == 2
            && x.GetParameters().Length == 2
            && x.GetParameters()[0].ParameterType == typeof(IEnumerable<>).MakeGenericType(x.GetGenericArguments()[0])
            && x.GetParameters()[1].ParameterType == typeof(Func<,>).MakeGenericType(x.GetGenericArguments())
            && x.ReturnType == x.GetGenericArguments()[1]);

TResult Max[TSource,TResult](System.Collections.Generic.IEnumerable`1[TSource], System.Func`2[TSource,TResult])

CodePudding user response:

Update: Found the issue
Method We Are Looking is :

TResult Max[TSource,TResult](System.Collections.Generic.IEnumerable`1[TSource], System.Func`2[TSource,TResult])

The Above Method in .net framework 4.7.2 was in first in list and the in .net 6 it was last in the list

So i changed the code to following

var maxOfStringMethod = (from method in typeof(Enumerable).GetMethods()
                where method.Name == "Max"
                      && method.GetParameters().Length == 2 &&
                      method.GetParameters()[1].ParameterType.GenericTypeArguments[2].IsGenericParameter
                select method).Last().MakeGenericMethod(new Type[] { typeof(SomeViewModel), typeof(string) });

And it worked.

  • Related