C# List Contains

List type

Contains scans a List. It searches for a specific element to see if that element occurs at least once in the collection. The C# List type has the useful Contains method that declaratively searches. It requires no explicit for-loop.

For

Example

Collections: circles in square

First, you will need to add the using System.Collections.Generic directive at the top of your source file to be using the List generic type. The Contains method is an instance method on the List type.

Note:This means you can only call it on a constructed List type. The List instance can have any type parameter.

Method call

The Contains method accepts a single parameter: the searched-for element. The LINQ Contains method accepts two parameters, with an additional IEqualityComparer instance that specifies how elements are compared for equality.

C# program that uses List Contains method

using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static void Main()
    {
	// 1. Create List with three elements.
	var list = new List<string>();
	list.Add("cat");
	list.Add("dog");
	list.Add("moth");

	// 2. Search for this element.
	if (list.Contains("dog"))
	{
	    Console.WriteLine("dog was found");
	}

	// 3. Search for this element in any string case.
	//    This is the LINQ method with the same name.
	if (list.Contains("MOTH", StringComparer.OrdinalIgnoreCase))
	{
	    Console.WriteLine("MOTH was found (insensitive)");
	}

	// 4. This element is not found.
	Console.WriteLine(list.Contains("fish"));
    }
}

Output

dog was found                         [Part 2]
MOTH was found (insensitive)          [Part 3]
False                                 [Part 4]
Var keyword

First, an implicitly typed local variable List is constructed with element type of string. Three string literal references are added to the collection's internal arrays through the Add method.

VarString LiteralList Add

The second method call uses two parameters, specifying the StringComparer.OrdinalIgnoreCase class that implements the IEqualityComparer interface. This allows an insensitive string search.

IEqualityComparerReturn keyword

Return value:Contains returns a bool value type. You can store its result in a bool. You can use the Contains method as an expression.

Bool

Discussion

System.Linq namespace

The System.Linq namespace is included by default in new Console applications in Visual Studio. It will allow you to call a separate Contains generic method on all IEnumerable types.

Contains

Note:The example in the program shows the Contains extension being used on the List type with a case-insensitive search.

Warning:LINQ extension methods are often slower. They operate on the IEnumerable interface.

IEnumerable Examples: LINQ, Lists and ArraysFramework: NET

Internally, Contains performs a linear search through the elements, starting with the first element, and uses Equals to check each element value. This is often much slower than a Dictionary. The LINQ method also does a linear search.

Performance

Cover logo

Next, I benchmarked the performance of List Contains and a custom for-loop on a small List. Only a few elements are searched by each method. As I expected, a custom for-loop was faster.

Benchmark

Tip:Typically writing a for-loop that does a search is faster than using a built-in method.

However:This approach creates extra code size, and this extra size may lead to performance decreases in larger programs.

List Contains benchmark: C#

using System;
using System.Collections.Generic;
using System.Diagnostics;

class Program
{
    /// <summary>
    /// Custom implementation.
    /// </summary>
    static bool ContainsLoop(List<string> list, string value)
    {
	for (int i = 0; i < list.Count; i++)
	{
	    if (list[i] == value)
	    {
		return true;
	    }
	}
	return false;
    }

    const int _max = 100000000;
    static void Main()
    {
	List<string> list = new List<string>();
	list.Add("one");
	list.Add("two");
	list.Add("three");
	list.Add("four");
	list.Add("five");

	var s1 = Stopwatch.StartNew();
	for (int i = 0; i < _max; i++)
	{
	    bool f = ContainsLoop(list, "four");
	}
	s1.Stop();
	var s2 = Stopwatch.StartNew();
	for (int i = 0; i < _max; i++)
	{
	    bool f = list.Contains("four");
	}
	s2.Stop();
	Console.WriteLine(((double)(s1.Elapsed.TotalMilliseconds * 1000000) /
	    _max).ToString("0.00 ns"));
	Console.WriteLine(((double)(s2.Elapsed.TotalMilliseconds * 1000000) /
	    _max).ToString("0.00 ns"));
	Console.Read();
    }
}

Results

19.22 ns For-loop, string comparisons [ContainsLoop]
54.60 ns Contains method              [Contains]

Based on:

.NET 4.5

Summary

We used the Contains method on the List generic type in the C# language. We saw how this method differs from the LINQ Contains method. The methods are generally implemented with a forward linear search.


C#: List