Search code examples
c#extension-methods

Extension methods for interfaces, which interface gets priority?


If I have a type that implements multiple interfaces, and have multiple same-named extension methods for the interface types that my type implements, what determines which extension method gets used?

In the case of a List<T>, if I have extension methods for ICollection<T> and IEnumerable<T>, then ICollection<T> is taking priority. If I add another extension that takes IList<T>, then IList<T> is taking priority over the other two methods. I thought maybe the order they were declared in the class was why, but that's not the case as IList<T> comes after the other two in the class definition.

Here's code I used to test it out:

using System;
using System.Linq;
using System.Collections.Generic;
                    
public class Program
{
    public static void Main()
    {
        var myList = new List<int>();       
        myList.IsNullOrEmpty();  // IList is used
        
        // Layout for List<T> in constructor
        //
        // public class List<T> : 
        //    ICollection<T>,
        //    IEnumerable<T>,
        //    ...,
        //    IList<T>,
        //    ...
    }
}

public static class Extensions
{
    public static bool IsNullOrEmpty<T>(this ICollection<T> collection)
    {
        Console.WriteLine("ICollection used.");
        return collection?.Count == 0;
    }

    public static bool IsNullOrEmpty<T>(this IEnumerable<T> enumerable)
    {
        Console.WriteLine("IEnumerable used.");     
        return enumerable == null || !enumerable.Any();
    }
    
    public static bool IsNullOrEmpty<T>(this IList<T> list)
    {
        Console.WriteLine("IList used.");       
        return list?.Count == 0;
    }
}

Solution

  • @TimSchmelter's comment on my question was the correct answer.

    IList<T> implements ICollection<T> and IEnumerable<T>, so it takes priority over those. And, ICollection<T> implements IEnumerable<T>, so it takes priority over it.

    IList<T> documentation

    ICollection<T> documentation