考虑以下代码:
public static class Extensions {
public static bool isEmpty<T>(this ICollection<T> collection) {
return collection.Count == 0;
}
public static bool isEmpty(this ICollection collection) {
return collection.Count == 0;
}
}
public class A {
IList<string> typedList;
IList rawList;
List<string> list;
public void b() {
bool d = typedList.isEmpty();
bool e = rawList.isEmpty();
}
}
上面的代码没有问题,IList
实现ICollection
和IList<T>
实现ICollection<T>
。如果我们要删除其中一个扩展方法,b()
中的一行将无法编译。这就是我宣布两种扩展方法的原因。但是,如果我们调用list.isEmpty()
:ambiguous call
,则会出现问题。但是,因为List<T>
实现了 ICollection
和 ICollection<T>
。如何环绕这个问题?当然,我可以添加扩展方法isEmpty(this List<T> list)
,但这自然不会修复任何其他同时实现类型化和非类型化接口的集合(并且适用于任何实现类型化和非类型化的非集合的集合)同一个界面的无类型版本。)
答案 0 :(得分:1)
您只需添加适用于所有序列的IEnumerable
扩展程序。
public static class Extensions
{
public static bool IsEmpty(this IEnumerable collection)
{
return !collection.Cast<object>().Any();
}
}
或者
public static class Extensions
{
public static bool IsEmpty(this IEnumerable collection)
{
IEnumerator enumerator = null;
try
{
enumerator = collection.GetEnumerator();
return !enumerator.MoveNext();
}
finally
{
IDisposable disposable = enumerator as IDisposable;
if (disposable != null)
{
disposable.Dispose();
}
}
}
}
答案 1 :(得分:1)
您可以使用反射来确定类型并调用正确的方法,但这可能是一种过度杀伤力。我建议创建一个扩展方法,该方法采用非泛型IEnumerable
并像这样实现它:
public static bool isEmpty(this IEnumerable collection)
{
var enumerator = collection.GetEnumerator();
if(enumerator.MoveNext()) return false;
return true;
}