18

私が知る限り、outパラメーターの唯一の用途は、呼び出し元が単一のメソッド呼び出しから複数の戻り値を取得できることです。refただし、代わりにパラメーターを使用して複数の結果値を取得することもできます。

では、パラメーターが有用であることが証明され、代わりにパラメーターをout使用できない状況は他にありますか?ref

ありがとうございました。

4

6 に答える 6

29

refはい-との違いはout、明確な割り当てに関するものです。

  • メソッド呼び出しの前に、呼び出し元がパラメーターを明確に割り当てる必要はoutありません。正常に戻る前に(つまり、例外なく)、メソッドで確実に割り当てる必要があります変数は、呼び出しに呼び出し元に確実に割り当てられます。

  • メソッドを呼び出す前に、呼び出し元がパラメーターを確実に割り当てる必要がありrefますメソッドで別の値を割り当てる必要はありません。

したがって、代わりint.TryParse(string, out int)に使用するように変更したいとします。ref通常、呼び出し元のコードは次のようになります。

int value;
if (int.TryParse(text, out value))
{
    // Use value
}
else
{
    // Do something else
}

ここで、を使用した場合、呼び出しの前に値を指定する必要があります。例refvalue

int value = 0;
if (int.TryParse(text, ref value))
{
    // Use value
}
else
{
    // Do something else
}

明らかにそれは大きな違いではありませんが、間違った印象を与えます。これまで使用するつもりのない値を割り当てているので、読みやすさには良くありません。outパラメータは、値メソッドから出力されること(例外がないと仮定)、および最初から値を持っている必要がないことを示します。

私がC#5に対して行った提案の1つ(取り上げられるかどうかはわかりません)は、outパラメーターを持つメソッドは、値のタプルを返すメソッドと見なすことができるはずであるというものです。タプルのより良いサポートと組み合わせると、次のようなことができるようになります。

var (ok, value) = int.TryParse(text);

この場合ok、とvalueはそれぞれに暗黙的に入力されboolますint。そうすれば、メソッドに何が入っているのか(text)と何が出てくるのか(2つの情報:okvalue)が明確になります。

代わりにパラメーターをint.TryParse使用した場合、これは単純に利用できません。コンパイラーは、パラメーターの初期値を実際に気にするかどうかを知ることができないためです。refref

于 2010-06-27T19:02:25.260 に答える
8

パラメータは次のように見ることができます。

  • 通常のパラメーターはパラメーター内にあります。
    値は、そのようなパラメーターを介して関数に入ることができます。したがって、初期化する必要があります。

  • refパラメーターは入出力パラメーターです
    。値は、そのようなパラメーターを介して関数に出入りできます。前者のため、初期化も必要です。

  • outパラメーターは出力パラメーターです
    。値は、そのようなパラメーターを介して関数から返されることのみが想定されています。したがって、初期化する必要はありません。

ref/outパラメータのこのような見方は、Microsoft の COM テクノロジを研究して思いつきました。IDL (インターフェース記述言語) は、COM コンポーネントのインターフェースを記述するために使用され、IDL では、パラメーターはinout、およびinout宣言子で拡張されます。.NET と C# は、これらの宣言子を COM から部分的に継承していると思われますが、名前は (refではなくinout) わずかに異なります。

COM ではout、インターフェイス メソッドの実際の戻り値を取得するためにパラメーターが頻繁に使用されます。これは、"実際の" 戻り値がHRESULT成功/エラー コードを返すために既に使用されていることが多いためです。

out.NET では、メソッドから複数の値を返したい場合でも、パラメーターの重要性ははるかに低いと思います (Tupleこれらの状況では複雑なオブジェクトまたは s を返すことができます)。

于 2010-06-27T19:18:51.290 に答える
4

1つの重要な違いはこれです:

out引数として渡される変数は、初期化する必要はありません。ただし、メソッドが戻る前に、outパラメーターに値を割り当てる必要があります。

(refパラメーターはこれを必要としません)

ソース: http: //msdn.microsoft.com/en-us/library/t3c3bfhx (VS.71).aspx

于 2010-06-27T19:03:59.313 に答える
2

outパラメータは、メソッドから複数の結果値が必要な場合に役立ちます。技術的には、パラメーターを使用refして同じ目標を達成することもできますが、パラメーターを使用outした方が意図を伝えるのにはるかに優れています。を使用する場合、関数の結果を使用する代わりに、または代わりに使用するref理由が明確ではありません。outおそらく、渡された値を変更するつもりですが、なぜそれを変更しているのかは、関数のシグネチャだけでは明らかではありません。

于 2010-06-27T19:08:31.357 に答える
2

良い例は int.TryParse() だと思います

http://msdn.microsoft.com/en-us/library/f02979c7.aspx

outがrefよりも優れている主な理由は、呼び出す前に (暗黙的であっても) ダミー値を return var に割り当てる必要がないことです。

したがって、 outはあなたとコンパイラーに次のように伝えます。

于 2010-06-27T19:43:48.080 に答える
0

2 つの主な違いは、refを使用している場合、呼び出しの前にこれを初期化する必要があり、メソッドでref変数に値を割り当てることはオプションであるということです。

ただし、outメソッドの場合、それらを明示的に初期化する必要はありませんが、メソッドでは何らかの値を代入する必要があります。そうしないと、コンパイル時エラーが発生します。

于 2010-06-28T04:47:03.653 に答える