protected IEnumerable <Benchmark> FindBenchmarks(IEnumerable <Type> types, BencharkSearchMethod searchMethod)
        {
            Debug.Assert(types != null);

            // Every benchmark class must be public and instantiable then it must have
            // a default constructor and it must not be a generic type.
            foreach (var type in types)
            {
                // Note that attribute may be used (to override name, description, etc) whatever
                // search method is. For example you may add attribute to change one specific benchmark name
                // keep searching them using by convention (using defaults for non decorated classes).
                var attribute = type.GetCustomAttribute <BenchmarkAttribute>();

                if (searchMethod == BencharkSearchMethod.Convention)
                {
                    // When discovering is performed by convention each benchmark class must start or with "Benchmark".
                    bool startsWith = type.Name.StartsWith(BenchmarkClassName, StringComparison.InvariantCultureIgnoreCase);
                    bool endsWith   = type.Name.EndsWith(BenchmarkClassName, StringComparison.InvariantCultureIgnoreCase);

                    if (!startsWith && !endsWith)
                    {
                        continue;
                    }

                    yield return(CreateBenchmarkForType(type, attribute));
                }
                else if (searchMethod == BencharkSearchMethod.Declarative)
                {
                    // When discovering is performed with a declarative syntax each benchmark class
                    // must be decorated with [Benchmark] attribute.
                    if (attribute == null)
                    {
                        continue;
                    }

                    yield return(CreateBenchmarkForType(type, attribute));
                }
                else
                {
                    // When discovering is BencharkSearchMethod.Everything then any eligible
                    // class in assembly catalog is considered a benchmark.
                    yield return(CreateBenchmarkForType(type, attribute));
                }
            }
        }
        private IEnumerable <BenchmarkedMethod> FindMethodsToBenchmark(Type type, BencharkSearchMethod searchMethod)
        {
            Debug.Assert(type != null);

            // Every eligible method must be public, must not have a return type and must not have any parameter.
            foreach (var method in GetInvokableMethods(type))
            {
                // Note that attribute may be used (to override name, description, etc) whatever
                // search method is. For example you may add attribute to change one specific benchmark name
                // keep searching them using by convention (using defaults for non decorated methods).
                var attribute = method.GetCustomAttribute <BenchmarkedMethodAttribute>();

                if (searchMethod == BencharkSearchMethod.Convention)
                {
                    // When by convention each bechmarked method must start with "Test".
                    if (!method.Name.StartsWith(BenchmarkMethodPrefix, StringComparison.InvariantCultureIgnoreCase))
                    {
                        continue;
                    }

                    yield return(CreateBenchmarkForMethod(method, attribute));
                }
                else if (searchMethod == BencharkSearchMethod.Declarative)
                {
                    // When declarative each method must be decorated with [BenchmarkedMethod] attribute.
                    if (attribute == null)
                    {
                        continue;
                    }

                    yield return(CreateBenchmarkForMethod(method, attribute));
                }
                else
                {
                    // When discovering is BencharkSearchMethod.Everything then any eligible
                    // method in each type is considered a benchmark.
                    yield return(CreateBenchmarkForMethod(method, attribute));
                }
            }
        }