メソッド作成時に手を抜く方法(メソッドが引数、無名メソッド)【C#】

ファイル名: -

使い分け

使い分けパターン 使用クラス ポイント

メソッドを引数に渡す方法

 

Func

<高階関数>

呼出先で、処理の切替を意識したくない時(呼び出し元で処理しておきたい時)に使える。
内部簡易メソッド

delegate+Funcなど

<ラムダ>

インナーメソッドなので変数を同じスコープで引き継ぎつつ内部の処理のようにかけるが、正式なメソッドのように引数をくどくきっちり渡さずに済む。
 

メソッドを引数に渡す方法

シーケンシャルに順番に処理されるのであれば、今までのやり方で不満はないが、その呼出先の真ん中で、ちょっと処理を変えたい時けど、呼出先では意識したくない時などに重宝する。

(A→X→B ) の処理と  (A→Y→B)みたいな処理。 業務タスクを処理する塊があったとして、 夜の場合の処理の仕方のメソッドを渡すか、日中帯の処理のメソッドを渡すかして、処理を少し呼び出し先の処理中に切り替えたい時に使う。
これでX,Yの部分のコーディングがすっきりする。関数を引数としても渡せることがLispの生産性の強み でもあったし、人工知能で世代間を書こうとすると遺伝アルゴリズムをそのまま渡すこの方式が一番書きやすい。

3ステップ

1.呼び出される(引数として渡される)メソッドはいつもの様に宣言する。

private int add(int v1,int v2){ ... } のような関数が定義されている想定。

2.メソッドを引数に取る時の引数の定義を、メソッド型で宣言するだけ

private static void totalDeal(Func<int, int, int> calc){ ... }

↑これは足し算/引き算のように、引数2つ取り、戻り値が int(3番目)のメソッドを calcという名前で受け付ける場合。

3.使う

totalDeal(add);  

Funcで事足りると思うけれども、例えば戻り値をVoidにしたい場合、Actionを使う。

さらにに省エネ

1ステップ目と3ステップ目をあわせる、無名メソッド(ラムダ式)の活用技がある。

totalDeal( (int v1 , int v2) => { return v1 + v2} ;);

 

内部簡易メソッド:無名メソッド

メソッドを呼ぶよりも、変化部分だけ引数で変えて渡すことができる引数の引き渡しを最小限にしてメソッドの恩恵を得られ、インナーメソッドのあるメソッドの中で整理しつつ名前をなしにできるところが楽できるポイント。インナーメソッドのようにメソッドの内部で微妙に繰り返したい時、メソッドを正式に作るより楽にできる。

使用の原則

3ステップ 1.クラスのように、delegateで型(返り値と引数)を宣言する。 delegate void MessageOut(string message);

※ delgate の前に public/private 等記載可能 2.インスタンス作成のように、メソッドの内部を定義する。

※ 定義された Out という同じ型のメソッドがあれば、  MessageOut action = this.Out; のようにも指定可能

3.使用する。

action("Hello! World!");

Action デリゲート (System) 

他の例

int 戻り値に、 int,intが引数の場合

delegate int sumTwo(int x, int y);

引数を増やしたり、片方だけ string や bool等にすることも可能です。

int(3つ目)が戻り値で、  (int, int)が引数の場合のFuncの定義

Func<int,int,int> func;

もう少し省エネ

クラスを宣言するのであれば、無名の意味がほぼ無いです。
C#では、System.Action<>の定義があり、最初のdelegateを省略できます。

今回の 場合 1ステップ目を省略し、3ステップ目は変更ありません。
void , stringのケース

Action<string> action = delegate(string msg)

 

目的の切り分け 事前定義されている型
戻り値あり、引数も自由自在:一番抽象的なメソッド  Func
戻り値 Void実行するだけのメソッド Action
戻り値bool、引数1個:属性を断定する。
いわゆる isVoid()  , isValid() , isNumeric()的な使い方
Predicate
戻り値int 引数2つ:ソートなどで使う比較 Comparison
戻り値任意、引数1つ:変換処理 Converter

ラムダ式

ラムダ式とは一般にメソッドの型を以下のように表現したもの。メソッドの中にメソッドがかける。しかもスコープは元とのまま。
(引数) => { 式の表現;  式の表現; ... }

例:
(int x , int y) => {  return x + y;};

これが、更に省略されて
(x,y)=> x+y
にもなる。

引数がない場合 最初のカッコも () => の形になる。

曖昧な表現になりそうだったらカッコ等で囲みましょう。

ラムダ式 (C# プログラミング ガイド)

ここまで来たら以下のプログラムが読めるようになると思います。

引数かどうかを返すラムダ式が中にあり、Countは配列の要素それぞれ 処理し trueの場合 +1します。結果奇数の数が求まります。

おまけ

ちなみに内部メソッド(ラムダ)のスコープはその上のメソッドのスコープも対象範囲になります(ラムダ式を読んでいるメソッド内のスコープも対象になる)。

関連ページリンク

アプリケーションの設定を保存しておく方法【C#】

デバッグや通知に便利なメッセージ通知方法の使い分け【C#】

座標操作のメソッドの使い分け【C#】

クリップボード操作方法の原則【C#】

アイコンイメージ3つの取得方法サンプルプログラム【C#】

キーエミュレート送信のまとめ【C#】【覚書メモ】

Bookmark this on Yahoo Bookmark
Buzz This
Bookmark this on Delicious
Bookmark this on Digg
Share on reddit
Share on LinkedIn
Bookmark this on @nifty clip
LINEで送る
email this
Pocket




コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です