只能通过IEnumerable枚举一次

时间:2019-04-29 11:57:12

标签: c#

给出以下代码(xUnit测试):

[Fact]
public void SetFilePathTest()
{
    // Arrange
    IBlobRepository blobRepository = null;
    IEnumerable<Photo> photos = new List<Photo>() 
    {
        new Photo()
        {
            File = "1.jpg"
        },
        new Photo()
        {
            File = "1.jpg"
        }
    };

    IEnumerable<CloudBlockBlob> blobs = new List<CloudBlockBlob>()
    {
        new CloudBlockBlob(new Uri("https://blabla.net/media/photos/1.jpg")),
        new CloudBlockBlob(new Uri("https://blabla.net/media/photos/2.jpg"))
    };

    // Act
    photos = blobRepository.SetFilePath2(photos, blobs);

    // Assert
    Assert.Equal(2, photos.Count());
    Assert.Equal(2, photos.Count());
}

这是SetFilePath2方法:

public static IEnumerable<T> SetFilePath2<T>(this IBlobRepository blobRepository, IEnumerable<T> entities, IEnumerable<CloudBlockBlob> blobs) where T : BlobEntityBase
{
    var firstBlob = blobs.FirstOrDefault();

    if (firstBlob is null == false)
    {
        var prefixLength = firstBlob.Parent.Prefix.Length;
        return entities
            .Join(blobs, x => x.File, y => y.Name.Substring(prefixLength), (entity, blob) => (entity, blob))
            .Select(x =>
            {
                x.entity.File = x.blob.Uri.AbsoluteUri;
                return x.entity;
            });
    }
    else
    {
        return Enumerable.Empty<T>();
    }
}

如您所见,我断言两次是同一件事。但是只有第一个断言成功。当我逐步使用调试器时,我只能枚举该集合一次。因此,在第二个Assert,它不会退回任何物品。

谁能解释我为什么会这样?除了解释这种行为外,我真的没有发现这段代码有任何问题。

1 个答案:

答案 0 :(得分:0)

每次致电.Count()时,您基本上都在致电 blobRepository.SetFilePath2(photos, blobs).Count(),然后在使用Select的同时修改实体。如果您不想改变原始值,我建议在new语句中使用Select。这就是为什么您获得不同结果的原因。