7

メソッド (および 2 つのメソッドに分割されるもの) から複数の値を返すには、次の方法を考えることができます。

private bool IsCarFaulty(Car car, out string fault)
{
  fault = string.Empty;
  return false;
}

private Tuple<bool, string> IsCarFaulty(Car car)
{
  return Tuple.Create(false, string.Empty);
}

private ResultAndMessage IsCarFaulty(Car car)
{
  return new ResultAndMessage(false, string.Empty);
}

private bool IsCarFaulty(Car car)
{
  return false;
}

private string GetCarFault(Car car)
{
  return string.Empty;
}

基本的に私の質問は、一方が他方よりも好ましい状況はありますか? 例としてint.TryParseを取り上げます。outパラメーターを使用していますが、2 つのメソッドに分割することはできませんでした。

4

6 に答える 6

4

分割メソッドCanParseParseメソッドの問題は、解析のコストを 2 回支払う必要があることCanParseですParse。これは、解析が非常に複雑で時間がかかる場合に特に問題になる可能性があります (たとえば、 のような型の場合DateTime)。

于 2012-08-17T23:48:32.303 に答える
3

複数の値が返される場合、厳密に型指定された「結果」オブジェクトを作成して、メソッドからの戻り値をカプセル化することを好みます。ただし、複数の値を返す必要があるということは、メソッドの処理が多すぎてリファクタリングできる可能性があることを示している可能性もあります。

たとえば、あなたのメソッドは、車が故障しているかどうかの bool とメッセージを返しています。メソッドが失敗の種類の列挙値を返すようにし、その値をエラー メッセージに変換するメソッドを持たないのはなぜですか?

于 2012-08-17T23:49:06.307 に答える
3

基本的に私の質問は、一方が他方よりも好ましい状況はありますか?

確かに、すべての場合に適用される一般的なルールはないと思います。ケースバイケースで、より快適に感じる方を選択してください。

outLinq ではうまく機能しないため、通常はパラメーターの使用を避けます。

例として int.TryParse を取り上げます。out パラメーターを使用していますが、2 つのメソッドに分割することはできませんでした。

確かにうまくいくかもしれませんが、それは文字列が 2 回解析されることを意味し、最適ではありません。

int.TryParse が導入されたとき、C# には null 許容型がありませんでした (編集: 実際にはありました)。今、あなたはそのようなメソッドを書くことができます:

public static int? TryParseInt32(string s)
{
    int i;
    if (int.TryParse(s, out i))
        return i;
    return null;
}
于 2012-08-17T23:50:40.923 に答える
2

オプション:

  1. out
    • 高速、それがフレームワークライブラリで使用される理由です、あなたはそれらの他のものと速度を交換することはできません
    • 悪いデザイン、LINQやチェーンコードとはうまく合いません
    • コーディングが簡単
  2. Tuple<>
    • 遅い、小さなオブジェクトを作成しますが、.NETで非常によく最適化されていると言われているため、実際には非常にコストがかかることはめったにありません。しかし、私はそれが問題になることが何度かありました。
    • 保守性が悪い、フィールドの名前がない、コードが自己文書化されていない
    • コーディングが簡単
  3. Result
    • スロー
    • 良好な保守性
    • より多くのコード

明らかに、あなたの特定のケースに何が良いかを誰も言うことができないので、あなた自身を選んでください。

于 2012-08-18T00:30:35.643 に答える
1

複数の値を返す最良の方法は、オブジェクト (すべての値をプロパティでラップするクラス) を返すことです。

private ResultAndMessage IsCarFaulty(Car car)
{
  return new ResultAndMessage(false, string.Empty);
}

2 つのプロパティ (bool と string) を持つクラス ResultAndMessage を使用

于 2012-08-17T23:52:17.130 に答える
0

いくつかの理由から、などのforメソッドboolで返すことを好みます。outTryXXXTryParseTryDeque

  1. 結果の「部分」は非常に別々のものであり、それらが別々に保たれているのが好きです.
  2. 戻り値の型は、これのすべてのバリアントで同じです。それで一貫しています。
  3. 型は、型自体 ( のように) または型への型パラメーター (およびのように)outのいずれかによって、呼び出された型またはオブジェクトに常に密接に関連付けられた型です。それで一貫しています。int.TryParseDictionary<TKey, TValue>.TryGetConcurrentQueue<T>.TryDequeue
  4. これは、.NET 内で簡単に認識できるパターンになりました。それで一貫しています。

最後のポイントには、他の何かがより適切な場合に人々がそれに目を向ける可能性があるというマイナス面があります (有効な入力と成功した操作を想定し、そうでない場合は例外をスローする方が良いことがよくあります)。

それ以外の場合は避けoutますが、チェーンがうまくいかないため、ラムダ式でもあまり便利ではありません。

それ自体がさらに使用される可能性が高い場合、さまざまな値をカプセル化するオブジェクトを好みます。それ以外の場合は、学習する別のクラスにすぎません。

何かが同時に2つの異なる値を返す明確な理由がある場合、私はタプルを好みますが、それ自体が新しい使用オブジェクトに関する上記と一致しません。

私は何よりもまず、単一の結果のみを返すことを好みます。

car-fault の例では、障害がなければ null になる可能性がある障害を表す単一のオブジェクトを返すか、"障害が見つからない" という値が取り得る車の状態を表す単一のオブジェクトを返します。 、または何よりも、車には複数の障害がある可能性があるため(実際、NCT / MOT /あなたの国と同等の直前にいくつかの高価なものを開発しているようです)、すべてを見つけるために反復またはクエリできる列挙可能またはクエリ可能なオブジェクト障害がない場合、( のように) 空になりますCount == 0

于 2012-08-18T00:14:45.013 に答える