2014年6月18日水曜日

C#応用 – LINQプログラミング 6



さて、C#応用 LINQプログラミング

第6回である。

応用編なので、まだまだ続くし
内容は濃い。


匿名メソッド
匿名メソッドはメソッドをわざわざ生成せずとも定義可能である。
これにより、イベント定義なども簡単なものであればインラインでできるようになる。

    delegate int MyDelegate(int i);
    class MyClass
    {
        public void Run()
        {
            MyDelegateL a = delegate(int i)
                            {
                                i++;
                                return i;
                            };
            Console.WriteLine(a(10));
        }

    }


ラムダ式
匿名メソッドでは受け渡しできたものはメソッドへの参照であり、コードの一部ではない。

    delegate int MyDelegateL(int i);
    class LambdaExpression
    {
        public void Run()
        {
            MyDelegateL a = (int i) => //  i という引数で扱う
                                    {        //   何か処理を行うのは{}の部分である
                                        i++;
                                        return i;
                                    };
            Console.WriteLine(a(10));
        }

    }



どちらで書いても、11を出力というのは変わらない。

1つだけで実行してるため、何とも味気ない結果である。




外部変数のキャプチャ
ラムダ式が上位スコープの変数を参照しているとき、その変数の寿命を
ラムダ式の寿命が尽きるまで延命する機能である。

delegate void MyDelegate();

MyDelegate GetSayMessageMethod()
{
    string msg = "Hello!";
    return () => {                // 引数がないことを明示している
        Console.WriteLine(msg);
    };
}

// 別メソッド
MyDelegate say = GetSayMessageMethod();

say();


(参考)定義済みdelegate
 ・ .NET Framework 3.5からサポートされるようになった

Action
 ・ 戻り値がvoidのdelegate
  ・ 引数をジェネリックで0個~4個まで指定できるActionが定義済み
  ex) Action<T1, T2, T3, T4>

Predicate<T>
  ・ 引数を1つに戻り値がboolのジェネリックなdelegate

Func<TResult>
  ・ ジェネリックで戻り値と引数を0個から4個まで指定できるdelegate
   ex) Func<T1, T2, T3, T4, TResult>

例によって 11  を出力するプログラムではこの様になる。
    class LambdaExpression2
    {
        public void Run()
        {
            Func<int, int>  a = (int i) =>
            {
                i++;
                return i;
            };
            Console.WriteLine(a(10));
        }

    }

前回の分を合わせ全部まとめて実行するとこうなる。

コードの方に#region という見慣れない

ディレクティブがある。


アウトラインで折りたたみや展開ができる機能らしい。

このように必要に応じて表示・非表示を切り替えたいデモの場合には最適だ。


列挙子とLINQ
取得した結果を簡単に扱うために必要である。

isInclude myInclude = delegate(string param)
    {
        if (param.StartsWith("新"))
        {
            return true;
        }
        else
        {
            return false;
        }
    };

var query = ary.Where(x => myInclude(x));

foreach(var item in query)    // この部分で使用される
    {
        Console.WriteLine(item);
    }


列挙子とは?
C# 1.X および.NET Framework 1.X では以下のような列挙をサポートするための

インターフェースが定義されている(変形のIterator)
C# 2.0以降では、ジェネリック版もある。

public interface IEnumerator
{
    bool MoveNext();
    object Current { get; }
    void Reset();
}

public interface IEnumerable
{
    IEnumerator GetEnumerator();
}

IEnumerable を実装すると

    public class Counter : IEnumerable
    {
        public int CountStop;

        public IEnumerator GetEnumerator()
        {
            return new CounterEnumerator(this);
        }
    }

そして、IEnumerator を実装すると

   public class CounterEnumerator : IEnumerator
    {
        private int _counter;
        private Counter myCounter;

        public CounterEnumerator(Counter counter)
        {
            myCounter = counter;
            Reset();
        }

        public bool MoveNext()
        {
            _counter++;

            return _counter <= myCounter.CountStop;
        }

        public object Current
        {
            get { return _counter; }
        }

        public void Reset()
        {
            _counter = 0;
        }
    }

利用するには、ということで



while を使う場合と

foreachを使う二通りが

挙げられている。






実行結果としては、どちらでやっても

1~10までを表示する。




今日の名言
愚か者は幸福がどこか遠いところにあると思い込んでいる。利口者は幸福を
足元に育てる。
                                 ジェイムズ・オッペンハイム

幸運は毎月やってくる。だがこれを迎える準備ができていなければ、ほとんど
見過ごしてしまう。今月こそ幸運を見逃すな。
                                 デール・カーネギー

人を幸福にするものは、どれだけたくさんのものを持っているかということではなく、
手持ちのものをどんなふうに楽しむかということである。
                                 チャールズ・H・スパーション

どんな時でもそうだが、今度も大変よい機会だ、それをどう扱うかさえ知っていれば。
                                 ラルフ・ワルド・エマーソン

人間の幸不幸は運によるところも大きいが、その人の気質によるところも、
これに劣らず大きい。
                                 ラ・ロシュフコー

チャンスが目の前に現れた時にこれをつかむ人間は、十中八九成功する。不慮の
事故を乗り越えて、自力で自分のチャンスをつくり出す人間は、百パーセント
成功する。
                                 デール・カーネギー