4

質問フィールドは少し短すぎて、私の本当の質問をすることはできません。誰かがそれをよりよく要約することができるならば、遠慮なくしてください。

私の本当の質問はこれです:私は最近C#で他の多くの人々のコードを読んでいて、ある特定の形式の反復が広く普及していることに気づきました(コードを参照)。
私の最初の質問は:

これらの反復はすべて同等ですか?

そして私の2番目は:なぜ最初のものを好むのですか?読みやすさと関係がありますか?最初のフォームは、慣れるとfor-formよりも読みやすくなるとは思いません。もちろん、これらの構成では、読みやすさは主観的な項目でありすぎます。もちろん、最もよく使用するものの方が読みやすいように見えます。しかし、for-formはすべて1行になっているので、少なくとも同じくらい読みやすいことを誰もが保証できます。また、構成の初期化を読み取​​ることもできます。

したがって、2番目の質問:なぜ3番目の形式がコードではるかに少なく見えるのですか?

        // the 'widespread' construct
        int nr = getNumber();
        while (NotZero(nr))
        { 
            Console.Write(1/nr);
            nr = getNumber();
        }

        // the somewhat shorter form
        int nr;
        while (NotZero(nr = getNumber()))           
            Console.Write(1 / nr);            

        // the for - form
        for (int nr = getNumber(); NotZero(nr); nr = getNumber())
            Console.Write(1 / nr);
4

7 に答える 7

5

このすべての反復は同等ですか?

はい

なぜ最初を好むのですか?それはsthです。可読性と関係がありますか?

while ループを超えて nr var のスコープを拡張したい場合があるためですか?

コードで 3 番目の形式があまり見られないのはなぜですか?

それは同等であり、同じステートメントです! nr 変数のスコープを拡張したくないので、後者を好むかもしれません。

于 2009-04-18T10:15:16.823 に答える
5

表示された 1 番目と 3 番目のフォームは、GetNumber への呼び出しを繰り返します。もちろん、条件内で副作用を使用するという欠点がありますが、私は2番目の形式を好みます。ただし、私はほとんどwhileループでのみそれを行います。ただし、通常、結果を引数として渡すことはありません。一般的な状況は次のとおりです。

string line;
while ( (line = reader.ReadLine()) != null)
...

int bytesRead;
while ( (bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0)
...

これらはどちらも私にとって非常に慣用的なものであり、問​​題を引き起こすことはありません.

変数のスコープが広すぎるのが気に入らない場合は、追加のブロックを導入できます。

{
  int bytesRead;
  while ( (bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0)
  {
     // Body
  }
}

個人的には、これを行う傾向はありません。「広すぎる」スコープはそれほど気になりません。

これらすべてをカプセル化するメソッドを作成するのはそれほど難しくないと思います。何かのようなもの:

ForEach(() => reader.ReadLine(), // Way to obtain a value
        line => line != null,    // Condition
        line =>
{
    // body
};

気をつけてください、行読みのために私は役立つクラスを持っています:

foreach (string line in new LineReader(file))
{
    // body
}

(ファイルだけでなく、非常に柔軟です。)

于 2009-04-18T10:20:28.667 に答える
3

3 番目の形式 (for ループ) は、物事を適切なスコープに入れるため、これらの選択肢の中で最適だと思います。一方で、getNumber() への呼び出しを繰り返さなければならないのも少し厄介です。

一般に、明示的なループは広く乱用されていると思います。高水準言語は、マッピング、フィルタリング、および削減を提供する必要があります。これらの高レベルの構造が適用可能で利用可能な場合、代わりにループすることは、ループの代わりに使用することに似てgotoいます。

マッピング、フィルタリング、または縮小が適用できない場合は、おそらくこの種のループ用に小さなマクロを作成します (ただし、C# にはそれらがありませんよね?)。

于 2009-04-18T10:33:56.933 に答える
3

私は別の選択肢を提供します

    foreach (var x in InitInfinite(() => GetNumber()).TakeWhile(NotZero))
    {
        Console.WriteLine(1.0/x);
    }

InitInfinite は簡単なヘルパー関数です。プログラム全体:

using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
    static IEnumerable<T> InitInfinite<T>(Func<T> f)
    {
        while (true)
        {
            yield return f();
        }
    }
    static int N = 5;
    static int GetNumber()
    {
        N--;
        return N;
    }
    static bool NotZero(int n) { return n != 0; }
    static void Main(string[] args)
    {
        foreach (var x in InitInfinite(() => GetNumber()).TakeWhile(NotZero))
        {
            Console.WriteLine(1.0/x);
        }
    }
}
于 2009-04-18T10:59:23.893 に答える
2

while() ループは、頭の中でタスクを視覚化する方法を最もよく表しているため、よく使用されると思います。他のループ構造よりもパフォーマンス上の利点があると思います。

于 2009-04-18T10:17:03.823 に答える
2

ここにランダムな推測があります:

私が C# コードを作成するとき、作成するループ構造は while() と foreach() の 2 つだけです。つまり、「foreach」はしばしば機能し、多くの場合優れているため、「for」を使用する人はもういません。(これは過度に一般化されていますが、真実の核心があります。) その結果、なじみのない 'for' ループを読み取るために脳が緊張する必要があります。

于 2009-04-18T10:20:30.337 に答える
1

(1)と(2)が(3)よりも「優先」される理由については、ほとんどの人が後者を、条件を使用して範囲を定義するのではなく、範囲を反復する方法として考えていると思います。いくつかの条件がまだ保持されている間、ブロックを繰り返します。キーワードのセマンティクスはこの解釈に役立ちます。その理由の1つとして、人々は表現がそのコンテキストで最も読みやすいと感じているのではないかと思います。たとえば、(1)または(2)を使用して範囲を反復処理することはできませんが、使用することはできません。

(1)と(2)の間で、私は引き裂かれました。以前はコンパクトさのために(2)(Cで)を使用することが多かったのですが、今では(C#で)一般的に(1)と書いています。コンパクトさよりも読みやすさを重視するようになったと思います。(1)少しのロジックを繰り返しても、すばやく解析できるため、頭の中で読みやすくなっているようです。

正直なところ、whileステートメントを作成することはめったにありません。通常、whileステートメントが以前に使用されていた場合はforeach(またはLINQ)を使用します。考えてみると、固定数のテストオブジェクトを生成する単体テストを除いて、ステートメントに多くを使用するかどうかもわかりません。

于 2009-04-18T12:17:18.510 に答える