1

我想知道 .net 框架中实现 IEnumerable 的任何类是否不实现 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();
    }

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

我的测试代码是:

[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());
    }
4

3 回答 3

2

只需使用任何 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 ...)

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

于 2016-06-15T11:26:14.157 回答
1

您可以使用Stack<T>该类,它实现ICollectionIEnumerable<T>不是ICollection<T>.

以下是类的定义方式:

public class Stack<T> : IEnumerable<T>, IEnumerable, ICollection, 
    IReadOnlyCollection<T>
于 2016-06-15T11:24:17.713 回答
0

他是一个IEnumerable<T>不是 a的例子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!!!
于 2016-06-15T11:27:50.653 回答