繁体   English   中英

我可以在 c# 中做类似 foreachwhile 循环的事情吗(这就是我将如何引用它)?

[英]can I do something like a foreachwhile loop(that's how I will be refering to it) in c#?

我已经研究了一些,但我找不到一个好的方法来做到这一点。 我有功能代码,但我想在不使用手动计数或中断的情况下清理它。 我查看了 LINQ 的 TakeWhile 函数,但在这种情况下这是不够的。 以下是功能等效的工作实现示例:

bool foo(List<strings> stringList, int counter)//assume this list has, like, 10 elements, and counter=3, idk
{
    ...

    bool found= false;
    for(int i=0; i<stringList.Count && !found; i++)
    {
        if(stringlist[i].length < 2 || counter >=6)
            found=true;
        counter++;
    }

    ...

    return found
}

我想用一些像这样的“魔法”功能来代替它:

bool foo(List<strings> stringList, int counter)//assume this list has, like, 10 elements, and counter=3, idk
{
    ...

    bool found= false;
    foreachwhile(string s in stringList while !found)
    {
        if(s.length < 2 || counter >=6)
            found=true;
        counter++;
    }

    ...

    return found
}

是否有一些函数可以做到这一点,如果没有,我该如何用 C# 编写一个......或者接近? 我经常发现我需要这样做,是的,我知道:

bool foo(List<strings> stringList, int counter)//assume this list has, like, 10 elements, and counter=3, idk
{
    ...

    bool found= false;
    foreach(string s in stringList)
    {
        if(found)
            break;
        if(s.length < 2 || counter >=6)
            found=true;
        counter++;
    }

    ...

    return found
}

从技术上讲也有效,但我想避免我的代码中断。 有没有其他干净的方法可以在 c# 中完成此操作?

编辑:我看到很多关于我在这里问的问题的困惑。 如果可能的话,我更喜欢添加一个非常明确的检查,如果可能的话,我们是否应该中断 foreach 语句本身,或者编写我自己的foreach版本,该版本接受一个参数,该参数仅在条件为真时继续,例如路径还没有找到。

另外,我很抱歉不清楚,但我想避免中断的最大原因是我不会在任意点跳出循环。 在这方面,回报同样是不可取的。

我也没有反对 Linq,我尝试使用它,但我发现它不会产生我正在寻找的功能:

bool foo(List<strings> stringList, int counter)//assume this list has, like, 10 elements, and counter=3, idk
{
    bool found= false;
    foreach(string s in stringlist.Takewhile(x=> (!found)))
    {
        if(s.length < 2 || counter >=6)
            found=true;
        counter++;
    }
    return found
}

与上面的逻辑不同,因为TakeWhile首先执行并返回一个空集,导致foreach循环没有任何内容可以循环。 如果有人有另一种方式来写这个,我真的很想听到它在语法上看起来非常干净。

循环前后都有其他代码的事实表明您应该重构代码以分离关注点。 如果您将逻辑片段分离到不同的位置,您的代码将会得到改进。 具有紧密耦合逻辑的长方法不可重用且难以维护。

例如,您的方法可以返回几个不同逻辑部分的逻辑组合,每个逻辑部分都委托给不同的方法。 显示的逻辑片段可以委托给另一种方法,如下所示。

我会使用break ,因为它旨在完全按照您的意愿执行操作,并且没有任何问题。 但是对于您的具体示例,您也可以避免像这样中断...

bool foo_part2(List<strings> stringList, int counter)
{
    foreach (string s in stringList)
    {
        if(s.length < 2 || counter >=6)
            return true;
        counter++;
    }
    return false;
}

...原始方法看起来像这样..

bool foo(List<strings> stringList, int counter)
{
    return foo_part1(stringList,counter) ||
        foo_part2(stringList,counter) ||
        foo_part3(stringList,counter);
}

(您可能需要使用&& s 而不是|| ,具体取决于所需的逻辑。)使用正确命名的方法(而不是这个“foo”示例),这可以很容易阅读,并且将避免您不得不查看函数来查看它在做什么。

然而,总而言之……这个问题有一个错误。 您声明“我也没有反对 Linq,我尝试使用它,但我发现它没有产生我正在寻找的功能......因为TakeWhile首先执行” 那是不正确的。 这意味着您没有亲自尝试,并且在问这个问题之前 20 分钟您没有理解上一个问题的答案 它使用谓词,因此每次迭代都会评估该值,这正是您想要的。 所以这整个问题是有缺陷的,如果你自己尝试过(甚至在问你之前的问题之前),你就会自己解决这个问题。

我向 OP 提到了Stack Overflow 用户期望多少研究工作的问题 .

不确定你的代码在做什么; 但是以下使用 Linq Any 实现了同样的事情。

bool foo(List<string> stringList, int counter)//assume this list has, like, 10 elements, and counter=3, idk
            {
                return stringList.Any(s =>
                {
                    var found = s.Length < 2 || counter >= 6;
                    counter++;
                    return found;
                });            
            }

如果您坚持不使用 break,另一种方法是使用委托,尽管使用 break 是最佳实践。

...

bool found= false;
Action Search = () =>
{
    foreach(string s in stringList)
    {
        if(s.length < 2 || counter >=6)
            found=true;
            return;
        counter++;
    }
}

Search();

...

不要使用此代码。 使用休息。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM