【问题标题】:Guid value changes when you don't use LINQ "ToList()" with Select() that returns IEnumerable当您不将 LINQ“ToList()”与返回 IEnumerable 的 Select() 一起使用时,Guid 值会发生变化
【发布时间】:2018-01-30 10:31:16
【问题描述】:

我有一个“测试”类,它有一个 IEnumerable 的具体对象

public class Test
{
    public IEnumerable<MyObject> MyObjects { get; }
}

public class MyObject
{
    public string Id { get; }


    public MyObject(
        string id,
    {
        this.Id = id;
    }
}

在调试 Specflow 功能文件使用的“Steps.cs”类时,我注意到“Id”的值发生了变化。 它们在“给定”步骤中符合预期,我将它们添加到 ScenarioContext

[Given("I have use case (.*)")]
{
    var _test = _retrieveTest.GetMyObjects(useCase);
    ScenarioContext.Current.Add("test", _test); 
}

当我在“When”步骤中从 ScenarioContext 中读取它们时,它们被更改了

[When("I do something")]
public void WhenIDoSomething()
{
    var _test = (MyProject.Entity.Test)ScenarioContext.Current["test"];         
} 

停止值更改的解决方案是在检索对象时使用 LINQ“ToList()”调用,如下所示:

private IEnumerable<MyObject> GetMyObjects(
        string usecase,
        MyProject.Entity.Test test)
    {
        ...
        return testData.Objects
            .Select(Object => {
                var _id = var _id = Guid.NewGuid();

                return new MyProject.Entity.MyObject(
                    _id);
            }).ToList();
    }

谁能解释为什么需要在这里调用“.ToList()”,而没有它为什么“Id”的值在“Given”和“When”步骤之间的“ScenarioContext”中发生变化

【问题讨论】:

  • ScenarioContext.Current 是一个目录。你确定你没有用另一个值覆盖一个键吗?
  • 是的,我确信我不会对它做任何事情,尤其是在 Given 和 When 步骤之间。我确实了解 ScenarioContext.Current 是什么以及它的用途。

标签: c# linq ienumerable specflow


【解决方案1】:

如果没有 .ToList(),您将返回一个 Enumerator,每次迭代它时都会执行该 Enumerator。 使用 .ToList() 您可以具体化枚举器并拥有一个具体的列表。

请参阅IEnumerable vs List - What to Use? How do they work? 以获得更详细的答案。

【讨论】:

  • 谢谢。这就解释了发生了什么。 Specflow ScenarioContext 是一个红鲱鱼!在进一步调查中,每次我打开 Quick Watch 窗口时,“Given”步骤中的“Id”都会发生变化,会生成不同的 Guid。由于它是一个 IEnumerable Guid.NewGuid();每次代码都会被调用,因为它被评估较晚,而不是当我使用“.ToList()”时,这使它成为后台的具体类型并保持原始的 Guid 值。我正在使用 IEnumerable,因为我喜欢使用只读集合来获得不变性的好处。
  • 如果您想要一个只读集合类型,请使用 IReadOnlyCollection 接口。 docs.microsoft.com/en-us/dotnet/api/… 我认为当你想要不变性时,它更适合作为 IEnumerable。
  • 感谢您的提示。我已编辑问题的原始标题以删除对 Specflow ScenarioContext 的引用,因为如前所述,这是一个红鲱鱼。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-12-03
  • 2012-06-26
  • 1970-01-01
  • 1970-01-01
  • 2014-11-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多