[解決済み] 戻り値とアウトパラメータはどちらが良いのでしょうか?
質問
あるメソッドから値を取得したい場合、このようにどちらかの戻り値を使用することができます。
public int GetValue();
または
public void GetValue(out int x);
両者の違いがよく分からないので、どちらが良いのか分からない。解説していただけませんか?
ありがとうございます。
解決方法は?
戻り値はほぼ
常に
は、そのメソッドが他に返すべきものを持っていない場合に正しい選択となります。(実際、私はこのようなケースで
これまで
voidメソッドに
out
パラメータを選択することができます。C# 7の
Deconstruct
メソッドは、このルールに対する非常に稀な例外として機能します)。
他のことはさておき、呼び出し側が変数を個別に宣言する必要がなくなるからです。
int foo;
GetValue(out foo);
対
int foo = GetValue();
また、このようなメソッドの連鎖を防ぐために、Out値を使用します。
Console.WriteLine(GetValue().ToString("g"));
(実際、これはプロパティセッターの問題点のひとつでもあり、ビルダーパターンがビルダーを返すメソッドを使う理由でもある、例えば
myStringBuilder.Append(xxx).Append(yyy)
.)
さらに、outパラメータはリフレクションで使うには若干難しく、通常、テストも難しくなります。(通常、アウトパラメータよりも戻り値のモックを容易にすることに、より多くの努力が払われます)。基本的に、私が思いつく限り、それらが 容易 ...
戻り値FTW。
EDIT: 何が起こっているかという点では・・・。
基本的に"out"のパラメータに引数を渡すときは、以下のようになります。 ある という変数が渡されます。(呼び出したメソッドは、パラメータ用のスタックに "new" 変数を持たず、あなたの変数を保存用に使用します。このとき、変数に変更があれば、すぐに確認することができます。以下に、その違いを示す例を示します。
using System;
class Test
{
static int value;
static void ShowValue(string description)
{
Console.WriteLine(description + value);
}
static void Main()
{
Console.WriteLine("Return value test...");
value = 5;
value = ReturnValue();
ShowValue("Value after ReturnValue(): ");
value = 5;
Console.WriteLine("Out parameter test...");
OutParameter(out value);
ShowValue("Value after OutParameter(): ");
}
static int ReturnValue()
{
ShowValue("ReturnValue (pre): ");
int tmp = 10;
ShowValue("ReturnValue (post): ");
return tmp;
}
static void OutParameter(out int tmp)
{
ShowValue("OutParameter (pre): ");
tmp = 10;
ShowValue("OutParameter (post): ");
}
}
結果
Return value test...
ReturnValue (pre): 5
ReturnValue (post): 5
Value after ReturnValue(): 10
Out parameter test...
OutParameter (pre): 5
OutParameter (post): 10
Value after OutParameter(): 10
この違いは、quot;post" の段階、つまりローカル変数やパラメータが変更された後である。ReturnValueテストでは、この違いは静的な
value
変数を使用します。OutParameterテストでは
value
という行で変更されます。
tmp = 10;
関連
-
[解決済み】WebResource.axdとは何ですか?
-
[解決済み] C#でenumからint値を取得する
-
[解決済み] なぜList<T>を継承しないのですか?
-
[解決済み] キーワード「ref」と「out」の違いは何ですか?
-
[解決済み] Entity Framework 5 レコードを更新する
-
[解決済み] 空のIEnumerableを返すにはどうしたらいいですか?
-
[解決済み】大文字・小文字を区別しない「Contains(string)
-
[解決済み】文字列の中にある文字列(実際はchar)の出現回数を数えるには?
-
[解決済み】文字列をパースしてNULL可能なint型にする方法
-
[解決済み】IEnumerable vs List - What to Use? どのように動作するのでしょうか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】エラー。「戻り値を変更できません」 C#
-
[解決済み】SmtpException: トランスポート接続からデータを読み取れません:net_io_connectionclosed
-
[解決済み] 'SubSonic.Schema .DatabaseColumn' 型のオブジェクトをシリアライズする際に、循環参照が検出されました。
-
[解決済み】Sequence contains no matching element(シーケンスにマッチする要素がない
-
[解決済み】Swashbuckle/Swagger + ASP.Net Core: "Failed to load API definition" (API定義の読み込みに失敗しました
-
[解決済み】値をNULLにすることはできません。パラメータ名:source
-
[解決済み】C#のequal to演算子でtextとvarcharのデータ型は互換性がない
-
[解決済み】Linq 構文 - 複数列の選択
-
[解決済み】エラー「必要なフォーマルパラメータに対応する引数が与えられていない」を解決する?
-
[解決済み】WebResource.axdとは何ですか?