GetMethodInfo Demo

CSharp · Console

/Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;

using static GetMethodInfoUtil;
using static GetIndirectMethodInfoUtil;

public class Program
{
	public static void Main(string[] args)
	{
		var methodInfos = new[] 
		{
			// Static methods
			GetMethodInfo<int, int>(Math.Abs),
			GetMethodInfo<double, double>(Math.Abs),
			GetMethodInfo<long, long, long>(Math.Max),

			// Static void methods
			GetMethodInfo(Console.Clear),
			GetMethodInfo<string[]>(Main),

			// With explicit cast if too many arguments
			GetMethodInfo((Action<string, object, object>)Console.WriteLine),

			// Instance methods
			GetMethodInfo<string, bool>("".StartsWith),
			GetMethodInfo(new List<int>().Clear),

		};

		int dummyInt;
		var moreMethodInfos = new[]
		{
			// Extracted from lambdas
			GetIndirectMethodInfo(() => "".StartsWith("")),
			GetIndirectMethodInfo((string s) => s.StartsWith(s)),
			GetIndirectMethodInfo(() => int.TryParse("", out dummyInt)),
		};

		foreach(var methodInfo in methodInfos.Concat(moreMethodInfos))
		{
			Console.WriteLine(methodInfo);
		}		
	}	
}

public static class GetMethodInfoUtil
{
	// No cast necessary
	public static MethodInfo GetMethodInfo(Action action) => action.Method;
	public static MethodInfo GetMethodInfo<T>(Action<T> action) => action.Method;
	public static MethodInfo GetMethodInfo<T,U>(Action<T,U> action) => action.Method;
	public static MethodInfo GetMethodInfo<TResult>(Func<TResult> fun) => fun.Method;
	public static MethodInfo GetMethodInfo<T, TResult>(Func<T, TResult> fun) => fun.Method;
	public static MethodInfo GetMethodInfo<T, U, TResult>(Func<T, U, TResult> fun) => fun.Method;

	// Cast necessary
	public static MethodInfo GetMethodInfo(Delegate del) => del.Method;
}

public static class GetIndirectMethodInfoUtil
{
	// Get MethodInfo from Lambda expressions
	public static MethodInfo GetIndirectMethodInfo(Expression<Action> expression) 
		=> GetIndirectMethodInfo((LambdaExpression)expression);
	public static MethodInfo GetIndirectMethodInfo<T>(Expression<Action<T>> expression) 
		=> GetIndirectMethodInfo((LambdaExpression)expression);
	public static MethodInfo GetIndirectMethodInfo<T, TResult>(Expression<Func<TResult>> expression) 
		=> GetIndirectMethodInfo((LambdaExpression)expression);
	public static MethodInfo GetIndirectMethodInfo<T, TResult>(Expression<Func<T, TResult>> expression) 
		=> GetIndirectMethodInfo((LambdaExpression)expression);

	// Used by the above
	private static MethodInfo GetIndirectMethodInfo(LambdaExpression expression)
	{
		if (!(expression.Body is MethodCallExpression methodCall))
		{
			throw new ArgumentException(
				$"Invalid Expression ({expression.Body}). Expression should consist of a method call only.");
		}
		return methodCall.Method;
	}
}
;