Search code examples
c#reflectionentity-framework-core

C# reflection get method with no parameters


I have this code:

MethodInfo method = typeof(AppDbContext)
     .GetMethod(nameof(AppDbContext.Set), BindingFlags.Public | BindingFlags.Instance);

There are two methods named Set in DbContext, Set<>() and Set<>(string name) the problem is, there is ambiguity with this code. So how do I get the method with no parameters?


Solution

  • For such reflection manipulations, usually I'm using simple helper class, which extracts MethodInfo from LambdaExpression.

    Your code can be simplified via this helper in the following manner:

    MethodInfo method = MemberHelper.MethodOfGeneric((AppDbContext ctx) => ctx.Set<object>());
    

    And helper class implementation:

    public static class MemberHelper
    {
        public static MethodInfo MethodOf<TResult>(Expression<Func<TResult>>                         methodCall) => GetMethodInfo(methodCall);
        public static MethodInfo MethodOf<T1, TResult>(Expression<Func<T1, TResult>>                 methodCall) => GetMethodInfo(methodCall);
        public static MethodInfo MethodOf<T1, T2, TResult>(Expression<Func<T1, T2, TResult>>         methodCall) => GetMethodInfo(methodCall);
        public static MethodInfo MethodOf<T1, T2, T3, TResult>(Expression<Func<T1, T2, T3, TResult>> methodCall) => GetMethodInfo(methodCall);
    
        public static MethodInfo MethodOfGeneric<TResult>(Expression<Func<TResult>>                         methodCall) => GetMethodInfo(methodCall).GetGenericMethodDefinition();
        public static MethodInfo MethodOfGeneric<T1, TResult>(Expression<Func<T1, TResult>>                 methodCall) => GetMethodInfo(methodCall).GetGenericMethodDefinition();
        public static MethodInfo MethodOfGeneric<T1, T2, TResult>(Expression<Func<T1, T2, TResult>>         methodCall) => GetMethodInfo(methodCall).GetGenericMethodDefinition();
        public static MethodInfo MethodOfGeneric<T1, T2, T3, TResult>(Expression<Func<T1, T2, T3, TResult>> methodCall) => GetMethodInfo(methodCall).GetGenericMethodDefinition();
    
        static MethodInfo GetMethodInfo(LambdaExpression lambda)
        {
            if (GetMemberInfo(lambda) is not MethodInfo methodInfo)
                throw new InvalidOperationException("Expression must be a method call expression.");
    
            return methodInfo;
        }
    
        static MemberInfo GetMemberInfo(LambdaExpression func)
        {
            return GetMemberInfo(func.Body);
        }
    
        static MemberInfo GetMemberInfo(Expression expr)
        {
            if (expr is MemberExpression memberExpr)
                return memberExpr.Member;
    
            if (expr is MethodCallExpression methodExpr)
                return methodExpr.Method;
    
            throw new InvalidOperationException("Expression must be a member expression or a method call expression.");
        }
    }
    

    It can be extended to get constructors, properties, etc.