IEnumerable<T> 的具体实现不是 ICollection<T>

concrete implemantation of IEnumerable<T> that is not ICollection<T>

我想知道 .net 框架中实现 IEnumerable 的 class 是否没有实现 ICollection 接口。

我问它是因为我写的以下扩展方法无法获得 100% 的代码覆盖率:

public static int GetSafeCount<T>(this IEnumerable<T> nullableCollaction)
    {
        if (nullableCollaction == null)
        {
            return 0;
        }
        var collection = nullableCollaction as ICollection<T>;
        if (collection != null)
        {
            return collection.Count;
        }
        return nullableCollaction.Count();
    }

最后一行没有包含在我的任何测试中,我找不到正确的 class 来实例化以覆盖它。

我的测试代码是:

[Test]
    public void GetSafeCount_NullObject_Return0()
    {
        IEnumerable<string> enumerable=null;

        Assert.AreEqual(0, enumerable.GetSafeCount());
    }
    [Test]
    public void GetSafeCount_NonICollectionObject_ReturnCount()
    {
        IEnumerable<string> enumerable = new string[]{};

        Assert.AreEqual(0, enumerable.GetSafeCount());
    }

您可以使用 Stack<T> class,它实现 ICollectionIEnumerable<T> 但不实现 ICollection<T>

class 的定义如下:

public class Stack<T> : IEnumerable<T>, IEnumerable, ICollection, 
    IReadOnlyCollection<T>

只需使用任何 LINQ 操作,例如Where:

[Test]
public void GetSafeCount_NonICollectionObject_ReturnCount()
{
    IEnumerable<string> enumerable = new string[0].Where(x => x.Length == 0);
    Assert.AreEqual(0, enumerable.GetSafeCount());
}

但是,您可以通过推迟到 Enumerable.Count() 来简化您的实施,我希望它可以按照您希望的方式进行优化:

public static int GetSafeCount<T>(this IEnumerable<T> nullableCollection)
    => nullableCollection == null ? 0 : nullableCollection.Count();

或:

public static int GetSafeCount<T>(this IEnumerable<T> nullableCollection)
    => nullableCollection?.Count() ?? 0;

(均假定为 C# 6...)

在这一点上,只有两个测试是有意义的:一个用于空参数,一个用于非空参数。

他是 IEnumerable<T> 而不是 ICollection<T> 的例子:

public class MyClass : IEnumerable<int>
{
    public List<int> ints = new List<int> { 1, 2, 3, 4, 5 };

    public IEnumerator<int> GetEnumerator()
    {
        foreach (var i in ints)
        {
            yield return i;
        }
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return this as IEnumerator;
    }
}

现在您可以这样做了:

foreach(var item in new MyClass())
{
    // do something
}

但不能这样做,因为它不是 ICollection

var coll = new MyClass() as ICollection<int>; // null!!!