Resharper 删除了 foreach 的产量。为什么?

Pau*_*der 5 c# resharper yield-return

我最近了解yield并创建了以下测试控制台程序:

    public static string Customers = "Paul,Fred,Doug,Mark,Josh";
    public static string Admins = "Paul,Doug,Mark";

    public static void Main()
    {
        var test = CreateEfficientObject();

        Console.WriteLine(test.Admins.FirstOrDefault());
        //Note that 'GetAllCustomers' never runs. 
    }

    public static IEnumerable<string> GetAllCustomers()
    {
        var databaseFetch = Customers.Split(',');
        foreach (var s in databaseFetch)
        {
            yield return s;
        }
    }

    public static IEnumerable<string> GetAllAdmins()
    {
        var databaseFetch = Admins.Split(',');
        foreach (var s in databaseFetch)
        {
            yield return s;
        }
    }

    static LoginEntitys CreateEfficientObject()
    {
        var returnObject = new LoginEntitys {};
        returnObject.Admins = GetAllAdmins();
        returnObject.Customers = GetAllCustomers();
        return returnObject;
    }
}
public class LoginEntitys
{
    public IEnumerable<String> Admins { get; set; }
    public IEnumerable<String> Customers { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

但我注意到 Resharper 想要将我的foreach循环转换为:

public static IEnumerable<string> GetAllCustomers()
{
    var databaseFetch = Customers.Split(',');
    return databaseFetch;
}
Run Code Online (Sandbox Code Playgroud)

为什么 Resharper 想要从这个案例中去除产量?它完全改变了功能,因为它将不再在没有产量的情况下延迟加载。我只能猜测

  • A)我使用yield不正确/实践不当
  • B) 这是一个 Resharper 错误/建议,可以忽略。

任何见解都会很棒。

Ser*_*rvy 4

您是对的,这个提议的转换以微妙的方式改变了代码的功能,防止它推迟属性的评估并Split尽早执行评估。

也许那些实现它的人很清楚这是功能上的变化,并认为它仍然是一个有用的建议,如果现有语义很重要,或者如果他们实际上没有意识到语义正在被改变,那么可以忽略这个建议。我们没有什么好办法知道,我们只能猜测。如果这些语义对您的程序很重要,那么您不进行建议的转换是正确的。

  • @itsme86那么你应该自己运行该程序来观察两个实现的不同输出,以便亲自查看。 (2认同)
  • @itsme86 问题不是问两者是否相同。OP“知道”它们不一样。他甚至编写了程序来证明这一点。他并不是在问为什么这两个程序的功能不同;而是在问为什么这两个程序的功能不同。他让我有充分的理由相信他确切地知道他们为何不同。他问 Resharper 为什么要进行他知道是功能性改变的转变。如果您想具体了解这些代码片段不同的原因,以及具体如何观察这些实现之间的差异,请随时将其作为一个新问题提出。 (2认同)