C#でRubyのArray#eachやInteger#timesが実現できる!

Rubyの最も強力な機能、それは手軽なブロック構文だ。

 

実行結果:

Money!
Money!
Money!

 
 

同じようなループをC#の文法で記述すると、Rubyのブロック構文を使用した場合と比べて、いくぶんか冗長な表現になってしまう。

int型iの宣言、ループ比較、iのインクリメント処理を全て自前で記述しているためだ。

C#の拡張メソッド

ところが、C#でも、拡張メソッドというものを使用することで、Rubyのようにループを表現することができるようになる。

 

あるいは1ループあたり複数の処理をさせたい場合はこのように{と}で囲む。

かなりRubyらしく記述できている。

 

ただしこのコードをC#で動作させるためには、次のような事前準備が必要だ。

これは拡張メソッドといって、ある型のインスタンスに、後付でメソッドを追加するという機能だ。

 
 

動作させるための全体的なコードはこのようになる。

 

実行結果:

Monkey!
Monkey!
Monkey!

 
 

拡張メソッドには様々な使い方があることにはあるが、個人的には今回のように、ブロック(C#ではlambdaという)を渡してRubyライクなループ処理を実現するというのが最も適した使い道ではないかと思う。

拡張メソッドの宣言方法

次の点を守ることで、拡張メソッドを宣言できる。

 

この拡張メソッドは、最初に紹介したものとは少し異なり、渡すブロック(lambda)にint引数がある。

そしてブロックの引数には、ループごとに、現在のループインデックスが割り当てられる。

 

こうすることで、現在が何ループ目なのかをブロックから把握することができる。

実行結果:

0 times rooping.
1 times rooping.
2 times rooping.

まさに、RubyのInteger#timesメソッドと同じ挙動が実現できた。

(ちなみに0インデックスなところは、RubyのInteger#timesメソッドと同じ挙動を意識している。)

RubyのArray#eachメソッドをC#で表現してみる

今度は、RubyのArray#eachメソッドをC#で表現してみる。

ジェネリック型で作成しているので、配列ならば何に対してでもEachメソッドを呼び出すことができるようになっている。

 

実行結果:

Today is Sunday
Today is Monday
Today is Tuesday
Today is 1
Today is 2
Today is 3
Today is 4
Today is 5

 
 

なんだかいい気分になってきたため、ついでなのでrubyのArray#each_with_indexもC#で実装してみた。

実行結果:

index : 0, string : Sunday
index : 1, string : Monday
index : 2, string : Tuesday

あとがき

今回、拡張メソッドを紹介するために作成したメソッド以外にも、もっと色々な拡張メソッドを作って、C#をもっとRubyライクに書いてほしい。

この記事を読んだRubyistが、C#での冗長な記述に悩まされているストレスを軽減することに成功してくれればうれしい。

 

コメントを残す

トラックバック: http://pgnote.net/wp-trackback.php?p=584