3

この投稿は、実際には下のコードのバグに関するものではありません。私自身、それを解決する方法が何十もあると想像できますが、主にシンプルさ、エレガンス、パフォーマンスに関連しています!

次のような非常に単純なテキスト パーサーを実行する必要がありました。

string ParseWord(ref string Line, ref int Pos) {
    // Inspect Line from Pos, increment Pos and return next Word
}

void ParseText(string[] Lines) {
    foreach (string Line in Lines) {
        int Pos = 0;
        string Word;
        while ((Word = ParseWord(ref Line, ref Pos)) != null) {
            // Do something with Word
        }
    }
}

残念ながら、「foreach」変数「Line」は許可されていない参照によって渡されるため、そのようには機能しません。

お気づきかもしれませんが、私は通常 C++ プログラマーです。私の考えでは、文字列を参照として渡す方が高速であると考えていました。これは、毎回コピーする必要がないためです。

最初の質問: その仮定は c# でも有効ですか?

2番目の質問:その「行」への参照を渡し、「foreach」を引き続き使用するにはどうすればよいですか-c#には「const」はありません

3 番目の質問: 不適切な C++ の方法を考えているのでしょうか?

4

3 に答える 3

11

いいえ、それは有効な仮定ではありません。デフォルトでは、C# は参照によって文字列を渡します。これは、内部でポインターが効率的に渡されることを意味します。

reforを使用して文字列を渡す唯一の理由outは、呼び出されるメソッドが文字列を変更する必要があり、その変更を呼び出し元のメソッドに反映する必要がある場合です。文字列は不変であるため、ターゲット メソッドで文字列を「変更」すると、実際には新しい文字列が作成されますが、最初に渡された文字列には影響しません。この場合、reforoutを使用すると、呼び出し元のメソッドのポインターが更新され、変更された新しい文字列を指すようになります。

文字列を変更しない場合は、通常どおり文字列を渡すだけで非常に効率的です。C# Concepts: Value vs Reference Typesなどの記事をお勧めします。

于 2013-01-03T00:37:37.300 に答える
4
  1. 文字列は参照型であるため、変数として渡すときに文字列をコピーしません。あなたはその参照を渡しているだけです。

  2. foreach必要なものにループを使用できるとは思いませんが、ループを使用することはできforます。

    for (int index = 0; index < Lines.Length; index++)
    {
        string Line = Lines[index];
        int Pos = 0;
        string Word;
        while ((Word = ParseWord(ref Line, ref Pos)) != null)
        {
            // Do something with Word
        }
    }
    
于 2013-01-03T00:37:41.600 に答える
0

各行を分割しないのはなぜですか:

void ParseText(string[] Lines)
{
    foreach (string Line in Lines)
    {
        foreach (string word in Line.Split(' '))
        {
            // Do something with Word
        }
    }
}
于 2013-01-03T00:38:28.603 に答える