C#完全に理解したマンになろう
ぶっちゃけこんなとこ読んでないで未確認飛行とか読んでください、これはしがないメモ書きです
色々と記事を書いたり作ったりして「なるほど、キミはエンジニアなんだね!」と認識はされているであろう自分ですが、実のところまともなコードは書けないし言語をきちんと勉強した事がまるでないので、最近個人的にアツい重めの言語C#をここらで一度理解すると多言語扱うときも楽になるんじゃないかなと思ったりしたので。(遅い)
Golangも好きなのですが継承がなかったりとかちょっと独特な設計なので、みんなだいすきオブジェクト思考な言語のベースとして今回はC#を選びました。「完全に理解した(笑)」になったら最近async/awaitが実装されたらしいRustあたりを触ってみたい
分岐とループとか
Switch
1 2 3 4 5 6 7 8 9 10 11 12 |
switch (hoge) { case 1: fuga(); break; case 2: piyo(); break; default: ahokusa(); break; } |
となるわけだが、C#はfalltroughを許可していないらしい。つまり
1 2 3 4 5 |
case 1: fuga(); case 2: piyo(); break; |
みたいなのができない。Goとかだとbreakを書かなくてもデフォルトでbreakしてくれるし、falltroughもできるので、明示的でわかりやすいといえばわかりやすいが、個別に全部break書くのがちょっと怠いし、忘れるともっと怠い。
falltroughしたいときは
1 2 3 4 5 6 7 8 |
case 1: case 2: fuga(); case 3: case 4: case 5: piyo(); break; |
とかするらしい。ほげー
IEnumerable<T>
「あい えにゅめらぶる」である。「あいいー にゅめらぶる」でも「いんたーねっとえくすぷろーらー にゅめらぶる」でもない。
平気な顔して本家Microsoftのチュートリアルにいきなり出てくるがなんなの一体どういうときに使うの、となるので。
このインターフェースを実装するとなんとforeachでコレクション処理ができるようになるらしい。
foreachの一般的な使い方としては
1 2 3 4 |
foreach(int i in collection) { Console.WriteLine(i); } |
とかやって配列の中身を列挙したりするわけだが、これができるのは配列やリストが内部でIEnumerableインターフェースを実装しているからであって、「配列はforeachできる!」ではなく「foreachはIEnumerableが実装されていれば使える!」である。
詳しいことは参考サイト様を見てほしい。
つまるところ、IEnumerableインターフェースはGetEnumeratorメソッドが実装されている必要があり、GetEnumeratorはIEnumeratorインターフェースを実装するクラスのインスタンスを返すことを保証する、ということらしい。
なんだかややこしくなってくるが、いきなり出てきたIEnumeratorというのはコレクションの現在の要素を取得したり、次の要素に勧めたり、最初の要素に戻ったりできる奴のことを指す。
そして毎度毎度IEnumeratorを実装するクラスを作るのは面倒なので、イテレータ(yield)というものがある。これはyield returnで要素が返される度に、コレクションの次の要素をforeachで処理できるような形で返すことができる。要はyield returnをするとIEnumeratorを返すことができるということである。
だからなんなのだと言うと、参考サイトにあるように
1 2 3 4 5 6 7 8 9 |
public IEnumerator GetEnumerator() { for (int i = 0; i < hoge.Length; i++) { if(i%2==0) yield return hoge[i]; } } } |
みたいな特殊なGetEnumeratorを実装したりできる。
これでようやく本家のコンソールアプリケーションチュートリアルにある
1 2 3 4 5 6 7 8 9 10 11 |
static IEnumerable<string> ReadFrom(string file) { string line; using (var reader = File.OpenText(file)) { while ((line = reader.ReadLine()) != null) { yield return line; } } } |
が何をしてるかわかりましたね。stringなIEnumerableを返すReadFormとかいうメソッドは「次の要素をよこしな」と言われると、テキストファイルの次の行を返してくれるわけであります。
謎のusing
いやちょっとまってくださいよ、
1 |
using System; |
のusingはわかるけど
1 2 3 4 5 6 7 |
using (var reader = File.OpenText(file)) { while ((line = reader.ReadLine()) != null) { yield return line; } } |
のusingって何??????
どうやら外部リソースを使用するときに使う構文のようです。
と言うのも、ファイルやデータベース、ネットワークなどの外部リソースを使用する.NETのクラスは、使ったあとにDispose()
メソッドを呼び出してリソースを開放しないと、他から利用できなくなったりメモリリークしたりと大変なことになるのです。
そのため
1 2 3 4 5 6 7 8 9 10 |
var reader = new StreamReader(@"Sample.txt"); try { string text = reader.ReadToEnd(); Console.WriteLine(text); } finally { reader.Dispose(); } |
finallyとかいうこれまた謎なもので確実にリソース開放してあげる必要があるのですが、どう考えてもこれを書くのは面倒。ということでusingを使うと上記コードは
1 2 3 4 5 |
using (var reader = new StreamReader(@"sample.txt")) { string text = reader.ReadToEnd(); Console.WriteLine(text); } |
となります。簡潔だしDispose()
を忘れることもなくなるので便利。
複数リソース読み込みとか多段usingとかの使い方もあるっぽいので詳しくは以下を。