Custom Contains() function I have the following function and I was wondering if anyone could come up with something more efficient.

It just has to split both the content and the search string and determine how many words are required to be matched before being true.

For example, 

"A dog can run.".ContainsV2("Red Dog Run", 4) = false

"A dog can run.".ContainsV2("Red Dog Run", 2) = true

"A dog can run.".ContainsV2("Red Dog Run") = true

"A dog can run.".ContainsV2("Red Dog Run", MatchAllWords: true) = false




/// &lt;summary&gt;
/// Checks to see if any of the words are contained in the string. 
/// &lt;/summary&gt;
/// &lt;param name="content"&gt;&lt;/param&gt;
/// &lt;param name="SearchString"&gt;Search string&lt;/param&gt;
/// &lt;param name="NumberOfMatches"&gt;Specify how many words have to match in the search string.
///  This value is automatically dropped when the user searches less words.
/// I.e. NumberOfMatches = 3 and the user searches 'Bob', NumberOfMatches gets set to 1.&lt;/param&gt;
/// &lt;param name="MatchAllWords"&gt;If set to true, all of the words in the search string must be contained in what's being checked&lt;/param&gt;
/// &lt;returns&gt;&lt;/returns&gt;
public static bool ContainsV2(this string content, string SearchString, int NumberOfMatches = 1, bool MatchAllWords = false)
{
    var matches = 0;
    var numberOfWords = SearchString.Split(' ').Length;
    // Update required number of matches
    NumberOfMatches = NumberOfMatches &gt; numberOfWords ? 
                    numberOfWords : 
                    NumberOfMatches;

    if (!string.IsNullOrEmpty(content) &amp;&amp; !string.IsNullOrEmpty(SearchString))
    {
        SearchString.Split(' ')
            .ToList()
            .ForEach(w =&gt; //Gets the index of each word after being split
                matches += content
                    .IndexOf(
                        StripNonAlphaNumeric(w), 
                        StringComparison.OrdinalIgnoreCase
                    ) &gt;= 0 ? 1 : 0
            );
    }
    if (MatchAllWords)
    {
        return matches == numberOfWords;
    }
    return matches &gt;= NumberOfMatches;
}
Here is my first review. See what you can make of it! I left comments for you. They always discuss the code right below.

It is bad style to leave documentation tags empty. Either have no param tag or fill all with appropriate descriptions:

/// &lt;param name="content"&gt;&lt;/param&gt;
/// &lt;param name="SearchString"&gt;Search string&lt;/param&gt;
/// &lt;param name="NumberOfMatches"&gt;Specify how many words have to match in the search string.


Too much implementation detail in my opinion:

/// This value is automatically dropped when the user searches less words.
/// I.e. NumberOfMatches = 3 and the user searches 'Bob', NumberOfMatches gets set to 1.&lt;/param&gt;


Self explanatory name:

/// &lt;param name="MatchAllWords"&gt;If set to true, all of the words in the search string must be contained in what's being checked&lt;/param&gt;


This is self explanatory, remove the line:

/// &lt;returns&gt;&lt;/returns&gt;


Use a more telling name like ContainsWords:

public static bool ContainsV2(this string content, string SearchString, int NumberOfMatches = 1, bool MatchAllWords = false)
{
    var matches = 0;
    var numberOfWords = SearchString.Split(' ').Length;


Don't use empty comments like "Sets a variable" or "Updates value". Explain it better or leave out the comment:

    // Update required number of matches


The ?: operator is hard to understand and not necessary here. Rather, use something like in my comment:

    // if (NumberOfMatches &gt; numberOfWords)
    // {
    //    NumberOfMatches = numberOfWords;
    // }
    NumberOfMatches = NumberOfMatches &gt; numberOfWords ? 
                    numberOfWords : 
                    NumberOfMatches;


You already split the search string above. Either don't check for null or do it in the beginning:

    if (!string.IsNullOrEmpty(content) &amp;&amp; !string.IsNullOrEmpty(SearchString))
    {


This is confusing. Reduce the complexity and nesting depth:

        SearchString.Split(' ')
            .ToList()
            .ForEach(w =&gt; //Gets the index of each word after being split
                matches += content
                    .IndexOf(
                        StripNonAlphaNumeric(w), 
                        StringComparison.OrdinalIgnoreCase
                    ) &gt;= 0 ? 1 : 0
            );
    }


Rather set this at the start of the function. It is confusing here:

    if (MatchAllWords)
    {
        return matches == numberOfWords;
    }
    return matches &gt;= NumberOfMatches;
}