簡體   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