我有一个方法,我想在我的解决方案中采取所有类似列表的对象.在.NET 4.5之前,这很简单:
public static T Method<T>(IList<T> list) { // elided }
但是,.NET 4.5引入了IReadOnlyList< T>,该方法也应该适用于此.
我不能仅仅改变签名以获取IReadOnlyList< T>,因为有些地方我将该方法应用于特定类型为IList< T>的东西.
该算法不能在IEnumerable< T>上运行,并且它太频繁地使用(并且具有太大的对象)以获取IEnumerable< T>.并创建一个新列表< T>每次通话.
我试过添加一个重载:
public static T Method<T>(IReadOnlyList<T> list) { // elided }
…但是这不会编译实现两个接口(T [],List< T>和许多其他类型)的任何东西,因为编译器无法确定使用哪种方法(特别烦人,因为它们具有相同的身体,所以没关系).
我不想添加带有T []和List< T>的Method的重载,以及实现这两个接口的所有其他类型.
我该怎么做到这一点?
解决方法
这可能是实际检查运行时类型有用的场合之一:
public static T Method<T>(IEnumerable<T> source) { if (source is IList<T> list) return Method(list); if (source is IReadOnlyList<T> readOnly) return Method(readOnly); return Method(source.ToList() as IList<T>); } private static T Method<T>(IReadOnlyList<T> list) { ... } private static T Method<T>(IList<T> list) { ... }
您仍需要复制代码,因为您需要为IList和IReadOnlyList单独实现,因为您没有可以利用的通用接口,但至少可以避免出现模糊的呼叫问题.