ベストプラクティス:関数の戻り値またはbyref出力パラメーター?

StackOverflow https://stackoverflow.com/questions/246814

  •  05-07-2019
  •  | 
  •  

質問

FindSpecificRowValueという関数を使用して、データテーブルを取得し、特定の値を含む行番号を返します。その値が見つからない場合は、呼び出し元の関数にそのことを示したいと思います。

次への最善のアプローチ:

  1. 見つからない場合はfalse、見つかった場合はtrue、見つかった行番号をbyref / outputパラメーターとして返す関数を記述する、または
  2. intを返し、行の値が見つからない場合は-999を返し、見つかった場合は行番号を返す関数を作成します。
役に立ちましたか?

解決

個人的には、そのメソッド名でも行いません。

代わりに2つのメソッドを作成します:

TryFindSpecificRow
FindSpecificRow

これはInt32.Parse / TryParseのパターンに従い、C#では次のようになります。

public static Boolean TryFindSpecificRow(DataTable table, out Int32 rowNumber)
{
    if (row-can-be-found)
    {
        rowNumber = index-of-row-that-was-found;
        return true;
    }
    else
    {
        rowNumber = 0; // this value will not be used anyway
        return false;
    }
}

public static Int32 FindSpecificRow(DataTable table)
{
    Int32 rowNumber;


    if (TryFindSpecificRow(table, out rowNumber))
        return rowNumber;
    else
        throw new RowNotFoundException(String.Format("Row {0} was not found", rowNumber));
}

編集:質問により適したものに変更されました。

他のヒント

失敗した関数は例外をスローする必要があります。

失敗が予想されるフローの一部である場合、帯域外の値を返すことは問題ありませんが、帯域外の値を事前に決定できない場合は例外です。その場合、例外をスローする必要があります。

オプションから選択する必要がある場合、オプション2を選択しますが、-999ではなく定数を使用します...

戻り値を Nullable として定義し、Nothingを返すこともできます。何も見つからない場合。

オプション2を選択します。-999ではなく、-1を使用すると思います。

リチャード・ハリソンは、名前付き定数が裸の-1または-999よりも優れていることは正しいです。

2、または戻り値が値が見つかったかどうかを示す他のバリエーションを使用します。

関数が返す(または参照を提供する)行の値は、値が見つかったかどうかをすでに示しているようです。値が見つからなかった場合、値を含まない行番号を指定しても意味がないように思われるため、戻り値は-1、Null、または特定の言語に適した他の値でなければなりません。それ以外の場合、行番号が返されたという事実は、値が見つかったことを示します。

したがって、値が見つかったかどうかを示すために、別の戻り値は必要ないようです。ただし、特定の言語のイディオムに適合し、その中で関数呼び出しが実行される方法であれば、タイプ1が適切な場合があります。

Go with 2)しかし、-1(または行への参照を返す場合はnull参照)を返します。 。

BTW -1はより受け入れやすく、広く使用されている「マジックナンバー」です。 -999よりも、それが「正しい」理由の唯一の理由です。 (そこに使用されている引用符は理由があります)。

しかし、これの多くはあなたが期待することと関係しています。アイテムは常にそこにあるべきですが、どこにいるのかわかりませんか?その場合、通常どおりインデックスを返し、ない場合はエラー/例外をスローします。

この場合、アイテムはそこにない可能性があり、それは問題ない状態です。これは、データテーブルにバインドするGridViewで選択されていない値のエラートラップです。

まだ言及されていない別のいくつかの可能性:

// Method 1: Supports covariance; can return default<T> on failure.
T TryGetThing(ref bool success); 

// Method 2: Does not support covariance, but may allow cleaner code in some cases
// where calling code would use some particular value in in case of failure.
T TryGetThing(T DefaultValue);

// Method 3: Does not support covariance, but may allow cleaner code in some cases
// where calling code would use some particular value in case of failure, but should
// not take the time to compute that value except when necessary.
T TryGetThing(Func<T> AlternateGetMethod);

// Method 4: Does support covariance; ErrorMethod can throw if that's what should
// happen, or it can set some flag which is visible to the caller in some other way.
T TryGetThing(Action ErrorMethod);

最初のアプローチは、Microsoftが共変インターフェイスのサポートが存在する前に開発した方法の逆です。最後はいくつかの点で最も用途が広いですが、使用するたびにいくつかの新しいGCオブジェクトインスタンス(クロージャとデリゲートなど)の作成が必要になる可能性があります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top