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

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

新規登録して質問してみよう
ただいま回答率
85.48%
C#

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

Q&A

4回答

1593閲覧

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

退会済みユーザー

退会済みユーザー

総合スコア0

C#

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

0グッド

0クリップ

投稿2017/11/11 13:06

現在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))); }

気になる質問をクリップする

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

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

投稿2017/11/11 13:09

maisumakun

総合スコア145183

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

こんにちは。

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

C#

1public float CalculateTodaysCost() 2{ 3 float cost=0; 4 AddFoodCost(ref cost); 5 AddTransportationCost(ref cost); 6 AddAmusementCost(ref cost); 7 return cost; 8} 9 10private void AddFoodCost(ref float cost){ 11 //Aランチなら+500、Bランチは+1000、あるいは両方 12} 13private void AddTransportationCost(ref float cost){ 14 //会社に行ったら+320、そうでなければ変化無し 15} 16private void AddAmusementCost(ref float cost){ 17 //食費、交通費が1000以下なら+2000、そうでなければランダムで500以内の数を追加 18}

【蛇足ですが】

今回は極力バグが起こらないように、コメントがなくても十分な可読性が保たれるようにメソッドの規模を最小限にしようと考えながら作業を進めています。

そのため名前がつけられそうな処理は全てメソッドとして独立させ、数行の処理しか無いメソッドを量産しているのですが、

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

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

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

投稿2017/11/12 02:47

Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

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

cost |> AddFoodCost |> AddTransportationCost |> AddAmusementCost

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

(AddFoodCost >> AddTransportationCost >> AddAmusementCost) cost

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

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

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

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

投稿2017/11/11 14:45

raccy

総合スコア21735

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

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

C#

1public float CalculateTodaysCost() 2{ 3 Func<float, float>[] funcs = 4 { 5 this.AddFoodCost, 6 this.AddTransportationCost, 7 this.AddAmusementCost, 8 }; 9 return Calc(0, funcs); 10} 11 12public float Calc( float initial, IEnumerable<Func<float, float>> funcs ) 13{ 14 foreach (var f in funcs) 15 initial = f( initial ); 16 return initial; 17}

投稿2017/11/13 00:19

編集2017/11/13 00:40
ebiryo

総合スコア797

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問