public static AstVisitAction Visit(this AstVisitor astVisitor, Ast ast) { var dispatchMethodInfos = from dmi in astVisitor.GetType().GetMethods() where dmi.Name.StartsWith("Visit") let parameterType = dmi.GetParameters().Single().ParameterType where parameterType.IsAssignableFrom(ast) orderby parameterType.GetDerivationRank(ast) select dmi; if (dispatchMethodInfos.Any()) { try { return((AstVisitAction)dispatchMethodInfos.First().Invoke(astVisitor, new[] { ast })); } catch (TargetInvocationException targetInvocationException) { throw targetInvocationException.InnerException; } } else { throw new InvalidOperationException(ast.ToString()); } }