17

C# ではStreamReader、ファイルを 1 行ずつ読み取るために a を使用しています。intまた、考えられるエラー メッセージの報告のために、現在の行の番号を に保持しています。

各行の読み取りにはいくつかのテストが伴います (たとえば、 で始まる行#はコメントであり、スキップする必要があります)。そのため、読み取り手順全体を関数に配置して、有用な行に遭遇するまで読み取りを続けることを計画しています。そしてその行を返します。遭遇EOFした場合、単純に を返しnullます。

この関数を として定義したときは賢いと思っていましたが、C# ではその関数内でstring read(StreamReader sr, out int lineNumber)次のようなことができないことがわかりました。lineNumber++おそらく、この関数呼び出しの前に変数が割り当てられているかどうかを知る方法がないため、変数がまだ割り当てられていないと想定しています。

問題は単純です: この変数がパラメーターであることをどのように指定できますかinout(それが用語だと思います。他のプログラミング言語のコンテキストで言及されているのを聞いたことがあります)。これはそもそも可能ですか?私はlineNumber自分のクラスのメンバーを作るつもりは絶対にないので、それはオプションではありません.

4

4 に答える 4

18

その場合、ref代わりにパラメータが必要ですout。キーワードを使用outすると、値の割り当て/インスタンス化の責任は、呼び出されたメソッドの呼び出し内にあります。呼び出されrefているメソッドの外にあります。

参照: ref と out をいつ使用するか

于 2013-05-02T08:00:58.493 に答える
1

out の代わりに ref キーワードを使用します。これにより、呼び出し元は呼び出し前に引数を初期化する必要があります。

MSDNから- ref (C#)

ref パラメーターに渡される引数は、最初に初期化する必要があります。これを、out パラメーターに渡す前に引数を明示的に初期化する必要がない out パラメーターと比較してください。

于 2013-05-02T08:02:20.660 に答える
1

参照はあなたが必要とするものです

MSDN

メソッド パラメーターの ref メソッド パラメーター キーワードにより、メソッドは、メソッドに渡された同じ変数を参照します。メソッドのパラメーターに加えられた変更は、制御が呼び出し元のメソッドに戻るときに、その変数に反映されます。

于 2013-05-02T08:02:29.517 に答える
1

誰もが言うように、単に使用できますref

あなたがそれを知っているように、私は別のアプローチを提案するつもりです。

テキスト行と行番号をカプセル化するだけの非常に単純なクラスであるIEnumerable<Line>whereを返すメソッドを作成できます。Line

public class Line
{
    public string Text;
    public int    Number;
}

次に、行を読み取る方法は次のようになります。

public IEnumerable<Line> ReadLines(StreamReader sr)
{
    int number = 0;

    while (true)
    {
        string line = sr.ReadLine();

        if (line == null)
            break;

        ++number;

        if (wantLine(line)) // Some predicate which decides if you want to keep the line.
            yield return new Line{Text = line, Number = number};
    }
}

次に、次のように使用できます。

public void Test()
{
    StreamReader sr = new StreamReader("Whatever");

    foreach (var line in ReadLines(sr))
    {
        if (line.Text == "SomeSpecialValue")
            doSomethingWith(line.Text, line.Number);
    }
}

これは書く手間がかかりますが、より明確なコードになると思います。また、行番号カウンターが完全に内部に隠されているという利点もありますReadLines()。(クラスのフィールドであるという意味では、クラスのメンバーではありません。メソッド内の単なるローカル変数です。)

于 2013-05-02T08:13:53.620 に答える