【问题标题】:AutoFixture IEnumerable<T> behavior with CreateMany()AutoFixture IEnumerable<T> 行为与 CreateMany()
【发布时间】:2011-05-31 00:34:39
【问题描述】:

查看here 的帖子时,看起来我应该能够使用CreateMany() 创建多个对象,使用foreach 迭代它们,然后将它们作为数组返回。

我看到的是每次迭代似乎每次都创建新对象。这是预期的行为吗?

要创建的实体:

public class TestEntity
{
    public int Id { get; private set; }
    public string SomeString { get; set; }
    public void SetId(int value)
    {
        this.Id = value;
    }
}

示例 Program.cs:

private static int id;

static void Main(string[] args)
{
    var fixture = new Fixture();
    IEnumerable<TestEntity> testEntities = 
      fixture.Build<TestEntity>().CreateMany(5);

    Output(testEntities);

    foreach (var testEntity in testEntities)
    {
        testEntity.SetId(id++);
        Console.WriteLine(
          string.Format("CHANGED IN FOREACH:: hash: {0}, id: {1}, string: {2}", 
          testEntity.GetHashCode(), testEntity.Id, testEntity.SomeString));
    }

    Output(testEntities);
}

private static void Output(IEnumerable<TestEntity> testEntities)
{
    foreach (var testEntity in testEntities)
    {
        Console.WriteLine(
          string.Format("hash: {0}, id: {1}, string: {2}", 
          testEntity.GetHashCode(), testEntity.Id, testEntity.SomeString));
    }
}

我创建了一个问题 here(如果这是预期行为,可能会被删除)。

编辑 2011-06-02

要获得我期望的行为,如果我不想修改 AutoFixture 行为,我可以使用扩展方法:

var fixture = new Fixture();
TestEntity[] testEntities = fixture.Build<TestEntity>().CreateMany(5).ToArray();

【问题讨论】:

    标签: c# autofixture


    【解决方案1】:

    这确实是预期的默认行为。这有很多原因,但基本上归结为,当您要求 IEnumerable&lt;T&gt; AutoFixture 时,实际上会竭尽全力确保您只得到您所要求的。

    这对许多人来说是令人惊讶的行为。好消息是您可以更改它。

    fixture.Customizations.Add(new StableFiniteSequenceRelay());
    

    这将改变行为,以便随后所有序列都稳定。您可以将该方法调用打包到Customization for better reusability 中。这可能看起来像这样(完全可选):

    public class StableFiniteSequenceCustomization : ICustomization
    {
        public void Customize(IFixture fixture)
        {
            fixture.Customizations.Add(new StableFiniteSequenceRelay());
        }
    }
    

    【讨论】:

    • 再一次出色的帮助!我已经接受了答案,但如果你能详细说明“AutoFixture 实际上竭尽全力确保你只得到你要求的东西?”,那将是 ++。也就是说,我可能需要一些关于我所要求的教育! :)
    • 深入的解释需要一个完整的博客文章本身(在未来看到曙光)。简短的回答是IEnumerable&lt;T&gt; 的“合同”只指定了一个迭代器。它与列表不同。不稳定的迭代器甚至生成器也适合这个界面。
    • 是的,yield 是实现的一部分 :)
    • 原来我已经写过那篇博文然后忘记了:blog.ploeh.dk/2011/04/18/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多