セミコロンを使わずにFizzBuzzが書きたーい!!(某Eテレ風に)
で、C言語でこの類の定番解?がこちら
C言語には順次演算子というものがありまして、あれもしーのこれもしーのでそれ返す、なんて芸当ができるわけですが、C#にこの演算子はありません。加えて、.NETFrameworkって成功したかを返さないメソッドが多いんですよねー。失敗したときだけ例外投げるvoidメソッド多し。
Console.WriteLineもまた例外ではなく、さあvoidメソッドをどうやってセミコロン無しで呼ぶか=bool-expressionにするか。
これは深夜にセミコロンと格闘した男達の物語である...
このパターンだとSystem.ConsoleのTypeを取得して、メソッドを検索して、実行して、という流れですね。
そしてこのあたりでお題がFizzBuzzに決まったようです。
追記:確かに使えるけど、実装依存ぽい(ideoneじゃ無理)
C言語には順次演算子というものがありまして、あれもしーのこれもしーのでそれ返す、なんて芸当ができるわけですが、C#にこの演算子はありません。加えて、.NETFrameworkって成功したかを返さないメソッドが多いんですよねー。失敗したときだけ例外投げるvoidメソッド多し。
Console.WriteLineもまた例外ではなく、さあvoidメソッドをどうやってセミコロン無しで呼ぶか=bool-expressionにするか。
これは深夜にセミコロンと格闘した男達の物語である...
解1.戻り値の型なんて知らなかった
実行時型情報で動的に呼び出す場合、戻り値の型に応じて何パターンも用意するのはあほらしいのでとりあえずobjectで(voidも含め)全て受け取る形になります。戻り値ゲット。このパターンだとSystem.ConsoleのTypeを取得して、メソッドを検索して、実行して、という流れですね。
解2.voidメソッドではありませんobject返すデリゲートです(キリッ
C#ではメソッドをそのままデリゲートに変換できるのですが、どういうわけか戻り値があるとごまかせたようです。後は同じ。そしてこのあたりでお題がFizzBuzzに決まったようです。
番外編.昔々STDOUTという物がありまして
Console.OutはTextWriterなので書き込んだ上で値を返すメソッドがないのですが、FileStreamというクラスにはBeginWriteという非同期書き込みメソッドがうんたらかんたら。つまりファイルとして標準出力開くことができれば・・・っ!
CreateFileできるはずのCONOUT$でうまくいかず、次の方法を見つけたのであっさりあきらめましたが。
解3.戻り値なしのラムダ式&DynamicInvoke
ポイントは二つ。- ラムダ式を使って可読性アップ
先の解だとメソッドと引数が離れてしまって見にくいですね。引数無しのラムダ式にまとめることで呪文と本体を見やすくできました。
- DynamicInvoke
戻り値無しのデリゲートだとInvokeが値を返してくれないということでごにょごにょしていましたが、DynamicInvokeだとデリゲートの型に関係なくobjectを返してくれるようです。
で、FizzBuzzがこちら。
そして朝になり
あーvoidでもis演算子使えたんだー(棒読み追記:確かに使えるけど、実装依存ぽい(ideoneじゃ無理)
warning CS0184: The given expression is never of the provided (`int') type