C# の文字列参照型はコードの動作と矛盾しますか?
MSDN で文書化されているように、C# では文字列は参照型です。ただし、次のコードは、この概念に疑問を投げかけると思われる、混乱を招く問題を引き起こします:
<code class="language-csharp">class Test { public static void Main() { string test = "before passing"; Console.WriteLine(test); TestI(test); Console.WriteLine(test); } public static void TestI(string test) { test = "after passing"; } }</code>
参照型の動作によっては、コンソールが「通過前」に出力し、次に「通過後」に出力することが期待されます。これは、文字列 test
が参照によって TestI
メソッドに渡され、そのメソッド内で文字列に加えられた変更が呼び出し元に反映される必要があるためです。
ただし、コードは実際には「before Pass」「before Pass」という出力を生成します。これは、文字列が値によって渡されることを示します。この動作は、文書化されている C# の文字列の参照型と矛盾します。
誤解: 参照渡し vs 参照渡し
混乱は、値による参照の受け渡しと参照によるオブジェクトの受け渡しの微妙な違いから生じます。 C# では、パラメーターはデータ型に関係なく、常に値によって渡されます。
参照型がメソッドに渡される場合、渡される値自体が参照であるため、「参照渡し」という用語が使用されます。ただし、これは、変数によって参照されるオブジェクトも参照によって渡されるという意味ではありません。
上記の例では、TestI
メソッドに渡される値は、「渡す前」の文字列への参照のコピーです。メソッド内でこの参照のコピーに加えられた変更は、メソッド外の元の参照には影響しません。
参照による参照の受け渡し: ref キーワード
実際に参照型を参照渡しするには、ref
キーワードを使用する必要があります。このキーワードは、パラメーターが既存の変数への参照であり、メソッド内でパラメーターに加えられた変更が元の変数に反映されることを示します。
<code class="language-csharp">class Test { public static void Main() { string test = "before passing"; Console.WriteLine(test); TestI(ref test); Console.WriteLine(test); } public static void TestI(ref string test) { test = "after passing"; } }</code>
ref
キーワードを含めることにより、コードは期待どおりに実行され、TestI
メソッドが test
変数によって参照される元の文字列を変更するため、「通過前」と「通過後」を出力します。
以上がメソッドに渡されたときに、C#の文字列参照タイプが値タイプのように動作するように見えるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。