接口扩展方法优先级:实现多接口的类型如何选择同名扩展方法?
多接口实现场景下同名扩展方法的调用优先级
当一个类型实现了多个带有同名扩展方法的接口时,编译器会优先选择最具体(派生程度最高)的接口对应的扩展方法,和类声明接口的顺序完全无关。
核心规则
扩展方法的匹配优先级由接口的继承层次决定:
- 继承链中越靠下的接口(即更具体、离实现类更近的接口),其扩展方法优先级越高。
- 若两个接口无继承关系,才会出现编译歧义(此时必须显式指定接口类型来调用)。
以List为例的说明
在测试场景中:
IList<T>继承自ICollection<T>,而ICollection<T>又继承自IEnumerable<T>,三者形成了IEnumerable<T> → ICollection<T> → IList<T>的继承链。- 因此
IList<T>是三者中最具体的接口,编译器会优先匹配它的IsNullOrEmpty扩展方法。 - 哪怕
IList<T>在List<T>的接口声明中排在最后,也不影响优先级——声明顺序和继承层次是两个完全独立的概念。
测试代码
using System; using System.Linq; using System.Collections.Generic; public class Program { public static void Main() { var myList = new List<int>(); myList.IsNullOrEmpty(); // 输出"IList used.",调用IList<T>的扩展方法 // List<T>的接口声明结构参考 // 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; } }
内容的提问来源于stack exchange,提问作者Nic Foster
相关产品推荐
相关产品推荐

