質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.98%

  • C#

    5795questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

C#で引数と戻り値が同じメソッドの書き方を省略することは出来ないか

受付中

回答 4

投稿

  • 評価
  • クリップ 0
  • VIEW 427
退会済みユーザー

退会済みユーザー

現在C#のコードを書いています。

今回は極力バグが起こらないように、コメントがなくても十分な可読性が保たれるようにメソッドの規模を最小限にしようと考えながら作業を進めています。
そのため名前がつけられそうな処理は全てメソッドとして独立させ、数行の処理しか無いメソッドを量産しているのですが、同じ様な文章が続くため何かより良い省略記法があるのではと思うようになってきました。
例えば下記の様な記述をした場合に、最初のメソッドの引数や戻り値を省略する記述方法があれば教えてください。

public float CalculateTodaysCost()
{
    float cost;
    cost = AddFoodCost(cost);
    cost = AddTransportationCost(cost);
    cost = AddAmusementCost(cost);
    return cost;
}

private float AddFoodCost(float cost){
    //Aランチなら+500、Bランチは+1000、あるいは両方
}
private float AddTransportationCost(float cost){
    //会社に行ったら+320、そうでなければ変化無し
}
private float AddAmusementCost(float cost){
    //食費、交通費が1000以下なら+2000、そうでなければランダムで500以内の数を追加
}

・privateメソッドの中身にはいくつかの条件分岐や計算があり、必要な情報はフィールドなどから取得し変更を加える変数以外は引数では渡さない。
・複数のprivateメソッドで引数に渡された変数を変更し、同じ変数に代入するため同じ型の戻り値として返す。

とりあえず下記の様な書き方は浮かびましたが可読性が悪すぎるので他に何か良い手段はありませんか。

public float CalculateTodaysCost()
{
    float cost;
    cost = AddAmusementCost(AddTransportationCost(AddFoodCost(cost)));
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 4

+3

「元の値段を渡して足し算する」メソッドである必要性がないのでしたら、「足すべき分だけ返す」メソッドとして、ばらばらに呼んで全部足す、というほうが不必要な依存関係もなくなっていいかなと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+1

パイプライン演算子がある言語に変更する

言語によってはパイプライン演算子(|>が多い)というのがあります。パイプライン演算子を使えば。

cost |> AddFoodCost |> AddTransportationCost |> AddAmusementCost

のような書き方ができます。C#を使っているのであれば、F#がお勧めです。同じ.NETですので、そのまま採用してもほとんど問題はありません。その他、パイプライン演算子がある言語では関数結合の演算子が用意されていることも多いので、そちらを用いるという手法もあります。

(AddFoodCost >> AddTransportationCost >> AddAmusementCost) cost

専用のオブジェクトにしてメソッドチェーン

cost自体を何か意味あるクラスのオブジェクトと考えて、そのメソッドとして実装するという手法です。

cost.AddFoodCost(food).AddTransportationCost(goCompany).AddAmusementCost()

のような呼び出しになるようにします。依存関係が逆転するため、場合によっては良い方法とは言えません。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+1

こんにちは。

ご提示のケースなら、refにすれば良いように思います。

public float CalculateTodaysCost()
{
    float cost=0;
    AddFoodCost(ref cost);
    AddTransportationCost(ref cost);
    AddAmusementCost(ref cost);
    return cost;
}

private void AddFoodCost(ref float cost){
    //Aランチなら+500、Bランチは+1000、あるいは両方
}
private void AddTransportationCost(ref float cost){
    //会社に行ったら+320、そうでなければ変化無し
}
private void AddAmusementCost(ref float cost){
    //食費、交通費が1000以下なら+2000、そうでなければランダムで500以内の数を追加
}

【蛇足ですが】

今回は極力バグが起こらないように、コメントがなくても十分な可読性が保たれるようにメソッドの規模を最小限にしようと考えながら作業を進めています。
そのため名前がつけられそうな処理は全てメソッドとして独立させ、数行の処理しか無いメソッドを量産しているのですが、

メソッド名にはとんちんかんな名前を付けてもコンパイルエラーになりません。その意味では「コメント」と同じです。目的も同じですね。メソッドが何をするものなのかの説明です。
コメントとの違いは、呼び出す時、定義と完全に同じ名前を指定しないとコンパイルエラーになる点だけですので、可読性という意味では大差ないです。寧ろ、あまり長い名前は付けるべきでないですし、長めの名前で良く似た別のメソッドがあると中々頭痛いですから、コメントより記述能力は確実に低いです。

更に、デバッグ時はコメントと同様メソッド名も信用してはいけません(適切でない名前かもしれないし、適切な場合でも読む側が思い込みで勘違いすることも多々あります)ので、一々定義を開いて見る必要があります。そのため、デバッグ効率が低下します。特に開発者とメンテンス者が異なる時は悲惨です。

つまり、細かすぎるメソッドの量産は、他のプロジェクトメンバーへ迷惑をかける可能性があります。
実は以前、細かすぎるメソッド量産に大迷惑をかけられたことがあります。時間のない中でリファクタリングするにも限界があり、頭が痛かったです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

私は質問者さんのやり方で可読性が高まったり、メンテナンス性が向上するとは思えないのですが、「ソッドの引数や戻り値を省略」する技術的な解決方法として以下でどうでしょうか?

public float CalculateTodaysCost()
{
   Func<float, float>[] funcs =
   {
       this.AddFoodCost,
       this.AddTransportationCost,
       this.AddAmusementCost,
   };
   return Calc(0, funcs);
}

public float Calc( float initial, IEnumerable<Func<float, float>> funcs )
{
    foreach (var f in funcs)
        initial  = f( initial );
    return initial;
}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.98%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • C#

    5795questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。