1. ホーム
  2. c#

[解決済み] 戻り値とアウトパラメータはどちらが良いのでしょうか?

2022-04-26 22:56:04

質問

あるメソッドから値を取得したい場合、このようにどちらかの戻り値を使用することができます。

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;