Skip to content

Instantly share code, notes, and snippets.

@FransBouma
Created July 21, 2015 08:49
Show Gist options
  • Save FransBouma/811cada12482b053ea06 to your computer and use it in GitHub Desktop.
Save FransBouma/811cada12482b053ea06 to your computer and use it in GitHub Desktop.
.NET 4.6 breaking change?
internal static MethodInfo QueryableAllPredicate = GetQueryableMethodInfo(typeof(Queryable), "All",
(TSource) => new[]
{
typeof(IQueryable<>).MakeGenericType(TSource),
typeof(System.Linq.Expressions.Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(TSource, typeof(bool)))
});
private static MethodInfo GetQueryableMethodInfo(Type declaringType, string methodName, Func<Type, Type[]> parameterTypeFactory)
{
return GetQueryableMethodInfo(declaringType, methodName, parameterTypeFactory.Method);
}
private static MethodInfo GetQueryableMethodInfo(Type declaringType, string methodName, MethodInfo parameterTypeFactory)
{
var factoryParameters = parameterTypeFactory.GetParameters();
var numberOfParameters = factoryParameters == null ? 0 : factoryParameters.Length;
var matchingMethods = declaringType.GetMember(methodName, MemberTypes.Method, BindingFlags.Public | BindingFlags.Static);
// as there can be overloads, we have to filter out the ones which don't have the same parameter types as the one we're looking for
// the parameter types of the method we're looking for are created by the factory specified.
MethodInfo toReturn = null;
foreach(MethodInfo matchingMethod in matchingMethods)
{
var genericArgumentsOfMatchingMethod = matchingMethod.GetGenericArguments();
var matchingMethodArguments = matchingMethod.GetParameters();
// invoke the factory by passing the generic arguments, this will invoke the func the factory MethodInfo is part of.
if(genericArgumentsOfMatchingMethod.Length == numberOfParameters)
{
var argumentTypes = (Type[])parameterTypeFactory.Invoke(null, genericArgumentsOfMatchingMethod); // FAILS ON .NET 4.6, Succeeds on previous versions
if(matchingMethodArguments.Select(p => p.ParameterType).SequenceEqual(argumentTypes))
{
// found one
toReturn = matchingMethod;
break;
}
}
}
return toReturn;
}
@FransBouma
Copy link
Author

object instanceValueToPass = null;
if(!parameterTypeFactory.IsStatic)
{
    instanceValueToPass = new object();
}
var argumentTypes = (Type[])parameterTypeFactory.Invoke(instanceValueToPass, genericArgumentsOfMatchingMethod);

fixes it. Now I have to test it on non .NET 4.5 code

(edit) code works on csc 5 and roslyn csc so is an OK fix for this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment