C#の勉強記録その6

はい。昨日は勉強しませんでした。

前回は列挙体(一つの変数を軸に複数の定数を定義して扱える)と例外の作り方(exceptionクラスを継承してオリジナルの例外を定義できる)、delegate(メソッドを格納できる変数を作る)、匿名メソッドとラムダ式delegateで作った変数に、メソッドの処理内容を直接記述して格納できる)までをまとめた。

event

イベント=何かが起こったときに通知をする仕組み。イベント発生時にどんな処理をさせるか、内容に融通を利かせるためにdelegateを用意しておくとよいらしい。具体的には以下のような感じ。

delegate void MyEventHandler();
class MyButton{
    public event MyEventHandler MyEvent;
    //この「event」を書くことで、イベントをこのクラスからだけ実行できるように制約を設けられる。privateに似てる?
    public void OnClicked(){
        if (MyEvent != null) {
        //実行時にdelegateに何も処理が登録されていないとエラーになるのでif文で回避したほうが無難
            MyEvent();
        }
    }
}

class Main{
    static void Main(){
    MyButton btn = new MyButton();
    //この時点ではbtnインスタンスのMyEvent()には何の処理も記載されていないので、この後定義すること
    btn.MyEvent += () => Console.WriteLine("button clicked");
    btn.OnClicked();
    }
}

これを実行すると、btn.OnClicked()の実行を引き金としてMyEvent()が実行され、通知処理(この場合はコンソールにbutton clickedが出力される)が実行される。

List

Collectionというデフォで用意されているクラスがある。データの集合を扱う。種類として、List,HashSet,Dictionaryなどが存在する。
これらを使うには、名前空間「Collections.Generic」を読み込んでおかなければならないので注意。

Listは配列によく似ている。特徴は『順番を持っている』ということ。

List<int> numbers = new List<int>();
こんな風に定義する。インスタンスの作成と似ているが、Listは<>の中に格納する値の型を記載しておく。値の追加は下記のように行う。

numbers.Add(30);
numbers.Add(50);

または

List<int> numbers = new List<int>() {30,50,100};

こんな感じ。配列と違い、要素数についていちいち最初に定義しなくていいので使い勝手がいい。

numbers[1] = 100;

というように何番目の値を扱うかを定義すればそこだけを編集できるし、

numbers.Count

とすれば現在の要素数を確認もできる。
全ての値を確認したければ

foreach(var number in numbers){
    Console.WriteLine(number);
}

とすればよい。

便利~~~!!!引き続き便利~~~!!!

HashSet

順番を持たない。また重複したデータを内部に格納できない。
定義はListと一緒。

HashSet<int> numbers = new HushSet<int>() {3,5,8,5};

こんな感じ。
ただ、この場合「5」が重複するので2つめの5は無視される。値をいじる場合、HashSetは順番を持たないので「n番目にこいつに格納した値を消そう!」ということはできない。

numbers.Add(9);
numbers.Remove(5);

というように、あくまで格納されている(する)値を直接記載する必要がある。また、今ある値が格納されているか知りたいときには

numbers.Contains(3);

という風にContainを使用するとtrueかfalseで教えてくれる。

 

Listが「番号が振られた箱に値を入れていく」というもので、HushSetは「大きな一つの袋に重複がないように値を入れていく」というイメージだ。

Dictionary

個人的に一番使いそうな気がした。
キーと値でデータを管理していく。iniファイルやxmlファイルに似ている。

Dictionary<string, int> settings = new Dictionary<string, int>(){
    {"akarusa",100},
    {"contrast", 50},
    {"denryoku", 30}
};

こんな感じ。左がキーで右が対応した値。
データの増やし方は今までと同じ。

settings.Add("ookisa", 2000);

こんな。値を取り出すときはキーを指定する。

Console.WriteLine(settings["akarusa"]);

こんな感じ。foreachですべての値を取り出すのが少し厄介で

foreach (KeyValuePair<string, int> setting in settings) {
    Console.WriteLine($"{setting.Key}: {setting.Value}");
}

こう書く。

List,HashSet,Dictionaryいずれも実用性が高い。

LINQ

ラムダ式と並んでよく聞くや~つ。ただ、僕が勉強しているサイト(ドットインストール)では部分的な機能の説明にとどまるようなので引き続き頑張る。

LINQはデータの集合(Collectionとか)から任意の値を取得する仕組み。
名前空間「Systems.Linq」を読み込んでおく必要がある。

データの取得方式にはSQL風のものとメソッド風のものがある。

SQL方式だと以下のような感じ。

var results = from price in prices
    where price * 1.08 > 50.0
    select price * 1.08;

SQLだと
FROM price
SELECT price * 1.08
WHERE price * 1.08 >50;
かな?SQLあんまり触ってないから自信ないけど…

これでデータの集合「prices」から、1.08をかけると50を超える値が抽出されてくる。

メソッド方式だと以下のような感じ

var results = prices
    .Select( n => n * 1.08)
    .Where(n => n > 50);

また出たねえ!ラムダ式
メソッド方式だと一度すべての値を1.08倍して、その中でもwhereの条件に合致するものを抽出するっていう感じなのでそこが違いかな。

書き方についてはどっちもそう変わらないので、個人的に後から追いやすそうなメソッド方式を使うかも。

 

今日はここまで!これでとりあえず僕が勉強したかった単元までは終わったので、次からはunityを使ったりしてみようかな。