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;
}
}
@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.