カテゴリー
C

独習C#第3版、P518 LINQ 簡単なクエリ

using System;
using System.Linq;

namespace Chapter01All
{
    class LinqSample1
    {
        static void Main()
        {
            int[] ary = { 10, 3, -4, 2, -8, 15 };
            var ans = from n in ary
                      where n > 0
                      select n;
            foreach (int x in ans)
                Console.WriteLine(x);
        }
    }
}

LINQの書き方を覚えれば、ラムダよりは楽そうです。

カテゴリー
C

独習C#第3版、P559 ステートメント形式のラムダの例

using System;
using System.Collections;

namespace Chapter01All
{
    delegate ArrayList PlusElementListUp(int[] x);
    class DelegateLambdaSample2
    {
        static void Main()
        {
            int[] a = { 10, -5, 3, -9, 5 };
            PlusElementListUp op = n =>
            {
                ArrayList data = new ArrayList();
                for(int i=0; i<a.Length; i++)
                {
                    if (a[i] > 0)
                        data.Add(a[i]);
                }
                return data;

            };

            ArrayList b = op(a);
            foreach (int x in b)
                Console.WriteLine(x);
        }
    }
}

delegateを使う場合でも、基本は使わない場合でも、書けることのようです。

using System;
using System.Collections;

namespace Chapter01All
{
    class DelegateLambdaSample2
    {
        static void Main()
        {
            int[] a = { 10, -5, 3, -9, 5 };
            ArrayList b = CheckArray(a);
            foreach (int x in b)
                Console.WriteLine(x);
        }
        static ArrayList CheckArray(int[] ary)
        {
            ArrayList data = new ArrayList();
            int j = 0;
            for (int i = 0; i < ary.Length; i++)
            {
                if (ary[i] > 0)
                    data.Add(ary[i]);
            }
            return data;
        }
    }
}

上の方を先にやって見て、delegateを使う方はそれを変更して見ました。

using System;
using System.Collections;

namespace Chapter01All
{
    delegate ArrayList PlusElementListUp(int[] x);
    class DelegateLambdaSample2
    {
        static void Main()
        {
            int[] a = { 10, -5, 3, -9, 5 };
            PlusElementListUp Op = (int[] n) =>
            {
                ArrayList data = new ArrayList();
                for(int i=0; i<a.Length; i++)
                {
                    if (n[i] > 0)
                        data.Add(n[i]);
                }
                return data;

            };

            ArrayList b = Op(a);
            foreach (int x in b)
                Console.WriteLine(x);
        }
    }
}

 PlusElementsListUpはint[] xの引数を持つので、PlusElementListUp Op = (int[] n)と書かないといけないかもしれませんが、一番上の様でも動くことは動いてるようでした。

カテゴリー
C

独習C#第3版、P559 ステートメント形式のラムダ

using System;

namespace Chapter01All
{
    delegate int Syukei(int x);
    class DelegateLambdaSample2
    {
        static void Main()
        {
            int a = 10;
            Syukei ans = n =>
            {
                int wa = 0;
                for (int i = 0; i <= n; i++)
                    if (n > 0)
                        wa += i;
                return wa;
            };
            Console.WriteLine(ans(a));
        }
    }
}

先ずは簡単な例から。

カテゴリー
C

独習C#第3版、P557 式形式のラムダ

using System;

namespace Chapter01All
{
    delegate int Kasan(int x, int y);
    delegate int Genzan(int x, int y);
    class DeleGateSample
    {
 
        static void Main()
        {
            Kasan OpKasan = (x, y) => x + y;
            Genzan OpGenzan = (x, y) => x - y;
 
            Console.WriteLine(OpKasan(10, 20));
            Console.WriteLine(OpGenzan(10, 20));
            Console.WriteLine(OpKasan(100, 200));
            Console.WriteLine(OpGenzan(100, 200));
        }
    }
}

 デリゲートとともに式形式のラムダを使用する場合は、2つの手順が必要です。ひとつ目は使用するデリゲートの型を宣言することです。ふたつ目はそのデリゲート型の変数を宣言して、その変数にラムダ式を代入する。

カテゴリー
C

独習C#第3版、P469 課題12、13

using System;

namespace Util
{
    delegate void EventHandler(string str);
    class Sender
    {
        public event EventHandler Notify;
        public void Fire(string str)
        {
            if (Notify != null)
                Notify(str);
        }
    }
}
namespace Prog
{ 
    class Reciever
    {
        public void OnNotify(string str)
        {
            Console.WriteLine(str + "さん、called");
        }
    }
    class Kadai12syou
    {
        static void Main()
        {
            Util.Sender evt = new Util.Sender();
            evt.Notify += delegate (string str)
            {
                Console.WriteLine(str);            
            };
            evt.Fire("太郎");
            Reciever objR = new Reciever();
            evt.Notify += objR.OnNotify;
            evt.Fire("次郎");
        }
    }
}

delegate,eventはパターンが決まってるようなので、覚えておくしかないでしょう。問題の意味がつかめなかったのですが、大体は良かったかも。

カテゴリー
C

独習C#第3版、P454 イベントハンドラーに匿名メソッドを使う

// とても簡単なイベントの例
 
using System;

// イベント用のデリゲートの宣言
delegate void MyEventHandler(int x); //←イベントで使うデリゲートを宣言する

// イベントの送信側のクラス
class MyEvent
{
    public event MyEventHandler SomeEvent; //←イベントを宣言する

    // イベント送信を実装したメソッド
    public void Fire(int x)
    {
        if (SomeEvent != null)
            SomeEvent(x); //←イベントを送信する
    }
}
class H2
{
    public void Handler2(int x)
    {
        Console.WriteLine("1から" + x + "迄の2乗の和");
        int wa = 0;
        for (int i = 1; i <= x; i++)
            wa += i * i;
        Console.WriteLine(wa + "\n");
    }
}

class EventDemo
{
    static void Main()
    {
        H2 objH2 = new H2();
        MyEvent evt = new MyEvent(); //←イベントを送信する側のインスタンスを作成する

        evt.SomeEvent += delegate(int x)
        {
            Console.WriteLine("1から" + x + "迄の和");
            int wa = 0;
            for (int i = 1; i <= x; i++)
                wa += i;
            Console.WriteLine(wa + "\n");

        };

        evt.SomeEvent += objH2.Handler2;

        // イベントを人為的に発生させる
        evt.Fire(20); //←イベントを発生させる

        evt.SomeEvent -= objH2.Handler2;
        evt.Fire(10);
    }
}

1からxまで集計する関数を匿名メソッドにしてみました。引数の例はなかったのですが、delegate(int x)でOKでした。2乗の集計は前のまま使います。イベントハンドラーのチェーンから匿名メソッドを削除う出来るか疑問ですが?

カテゴリー
C

独習C#第3版、P452 マルチキャストイベント

// とても簡単なイベントの例
 
using System;

// イベント用のデリゲートの宣言
delegate void MyEventHandler(int x); //←イベントで使うデリゲートを宣言する

// イベントの送信側のクラス
class MyEvent
{
    public event MyEventHandler SomeEvent; //←イベントを宣言する

    // イベント送信を実装したメソッド
    public void Fire(int x)
    {
        if (SomeEvent != null)
            SomeEvent(x); //←イベントを送信する
    }
}

class EventDemo
{
    static void Handler(int x)
    {
        Console.WriteLine("1から10迄の和");
        int wa = 0;
        for (int i = 1; i <= x; i++)
            wa += i;
        Console.WriteLine(wa);
       
    }
    static void Handler2(int x)
    {
        Console.WriteLine("1から10迄の2乗の和");
        int wa = 0;
        for (int i = 1; i <= x; i++)
            wa += i * i;
        Console.WriteLine(wa);
       
    }

    static void Main()
    {
        MyEvent evt = new MyEvent(); //←イベントを送信する側のインスタンスを作成する

        // ハンドラをイベントリストに追加する
        evt.SomeEvent += Handler; //←イベントのチェーンにハンドラを追加する
        evt.SomeEvent += Handler2;

        // イベントを人為的に発生させる
        evt.Fire(10); //←イベントを発生させる
    }
}

HandlerとHandler2がMainと同じクラスclass EventDemoで、staticで構成されている。

// とても簡単なイベントの例
 
using System;

// イベント用のデリゲートの宣言
delegate void MyEventHandler(int x); //←イベントで使うデリゲートを宣言する

// イベントの送信側のクラス
class MyEvent
{
    public event MyEventHandler SomeEvent; //←イベントを宣言する

    // イベント送信を実装したメソッド
    public void Fire(int x)
    {
        if (SomeEvent != null)
            SomeEvent(x); //←イベントを送信する
    }
}
class H1
{
    public void Handler(int x)
    {
        Console.WriteLine("1から" + x + "迄の和");
        int wa = 0;
        for (int i = 1; i <= x; i++)
            wa += i;
        Console.WriteLine(wa);
    }
}
class H2
{
    public void Handler2(int x)
    {
        Console.WriteLine("1から" + x + "迄の2乗の和");
        int wa = 0;
        for (int i = 1; i <= x; i++)
            wa += i * i;
        Console.WriteLine(wa);
    }
}

class EventDemo
{
    static void Main()
    {
        H1 objH1 = new H1();
        H2 objH2 = new H2();
        MyEvent evt = new MyEvent(); //←イベントを送信する側のインスタンスを作成する

        // ハンドラをイベントリストに追加する
        evt.SomeEvent += objH1.Handler; //←イベントのチェーンにハンドラを追加する
        evt.SomeEvent += objH2.Handler2;

        // イベントを人為的に発生させる
        evt.Fire(20); //←イベントを発生させる
    }
}

HandlerとHandler2を別のクラスに分けて、インスタンスにHandlerを含ませてみました。

// とても簡単なイベントの例
 
using System;

// イベント用のデリゲートの宣言
delegate void MyEventHandler(int x); //←イベントで使うデリゲートを宣言する

// イベントの送信側のクラス
class MyEvent
{
    public event MyEventHandler SomeEvent; //←イベントを宣言する

    // イベント送信を実装したメソッド
    public void Fire(int x)
    {
        if (SomeEvent != null)
            SomeEvent(x); //←イベントを送信する
    }
}
class H1
{
    public void Handler(int x)
    {
        Console.WriteLine("1から" + x + "迄の和");
        int wa = 0;
        for (int i = 1; i <= x; i++)
            wa += i;
        Console.WriteLine(wa + "\n");
    }
}
class H2
{
    public void Handler2(int x)
    {
        Console.WriteLine("1から" + x + "迄の2乗の和");
        int wa = 0;
        for (int i = 1; i <= x; i++)
            wa += i * i;
        Console.WriteLine(wa + "\n");
    }
}

class EventDemo
{
    static void Main()
    {
        H1 objH1 = new H1();
        H2 objH2 = new H2();
        MyEvent evt = new MyEvent(); //←イベントを送信する側のインスタンスを作成する

        // ハンドラをイベントリストに追加する
        evt.SomeEvent += objH1.Handler; //←イベントのチェーンにハンドラを追加する
        evt.SomeEvent += objH2.Handler2;

        // イベントを人為的に発生させる
        evt.Fire(20); //←イベントを発生させる

        evt.SomeEvent -= objH1.Handler;
        evt.Fire(10);
    }
}

イベントチェーンから、objH1.Handlerを削除して、イベントを発生させてみました。

カテゴリー
C

独習C#第3版、P449 イベント

// とても簡単なイベントの例
 
using System;

// イベント用のデリゲートの宣言
delegate void MyEventHandler(int x); //←イベントで使うデリゲートを宣言する

// イベントの送信側のクラス
class MyEvent
{
    public event MyEventHandler SomeEvent; //←イベントを宣言する

    // イベント送信を実装したメソッド
    public void Fire(int x)
    {
        if (SomeEvent != null)
            SomeEvent(x); //←イベントを送信する
    }
}

class EventDemo
{
    static void Handler(int x)
    {
        Console.WriteLine("1から10迄の和");
        int wa = 0;
        for (int i = 1; i <= x; i++)
            wa += i;
        Console.WriteLine(wa);
    }
    static void Handler2(int x)
    {
        Console.WriteLine("1から10迄の2乗の和");
        int wa = 0;
        for (int i = 1; i <= x; i++)
            wa += i * i;
        Console.WriteLine(wa);
    }

    static void Main()
    {
        MyEvent evt = new MyEvent(); //←イベントを送信する側のインスタンスを作成する

        // ハンドラをイベントリストに追加する
        evt.SomeEvent += Handler; //←イベントのチェーンにハンドラを追加する
        evt.SomeEvent += Handler2;

        // イベントを人為的に発生させる
        evt.Fire(10); //←イベントを発生させる
    }
}

上の例は下を変更しました。

// とても簡単なイベントの例
 
using System;

// イベント用のデリゲートの宣言
delegate void MyEventHandler(); //←イベントで使うデリゲートを宣言する

// イベントの送信側のクラス
class MyEvent
{
    public event MyEventHandler SomeEvent; //←イベントを宣言する

    // イベント送信を実装したメソッド
    public void Fire()
    {
        if (SomeEvent != null)
            SomeEvent(); //←イベントを送信する
    }
}

class EventDemo
{
    static void Handler()
    {
        Console.WriteLine("1から10迄の和");
        int wa = 0;
        for (int i = 1; i <= 10; i++)
            wa += i;
        Console.WriteLine(wa);
    }
    static void Handler2()
    {
        Console.WriteLine("1から10迄の2乗の和");
        int wa = 0;
        for (int i = 1; i <= 10; i++)
            wa += i * i;
        Console.WriteLine(wa);
    }

    static void Main()
    {
        MyEvent evt = new MyEvent(); //←イベントを送信する側のインスタンスを作成する

        // ハンドラをイベントリストに追加する
        evt.SomeEvent += Handler; //←イベントのチェーンにハンドラを追加する
        evt.SomeEvent += Handler2;

        // イベントを人為的に発生させる
        evt.Fire(); //←イベントを発生させる
    }
}

こっちが最初です。

// とても簡単なイベントの例
 
using System;

// イベント用のデリゲートの宣言
delegate int MyEventHandler(int x); //←イベントで使うデリゲートを宣言する

// イベントの送信側のクラス
class MyEvent
{
    public event MyEventHandler SomeEvent; //←イベントを宣言する

    // イベント送信を実装したメソッド
    public void Fire(int x)
    {
        if (SomeEvent != null)
            Console.WriteLine(SomeEvent(x)); //←イベントを送信する
    }
}

class EventDemo
{
    static int Handler(int x)
    {
        Console.WriteLine("1から10迄の和");
        int wa = 0;
        for (int i = 1; i <= x; i++)
            wa += i;
        Console.WriteLine(wa);
        return wa;
    }
    static int Handler2(int x)
    {
        Console.WriteLine("1から10迄の2乗の和");
        int wa = 0;
        for (int i = 1; i <= x; i++)
            wa += i * i;
        Console.WriteLine(wa);
        return wa;
    }

    static void Main()
    {
        MyEvent evt = new MyEvent(); //←イベントを送信する側のインスタンスを作成する

        // ハンドラをイベントリストに追加する
        evt.SomeEvent += Handler; //←イベントのチェーンにハンドラを追加する
        evt.SomeEvent += Handler2;

        // イベントを人為的に発生させる
        evt.Fire(10); //←イベントを発生させる
    }
}

HandlerとHandler2をreturnする関数にしてみましたが、evt.Fire(10)ではHandler2のreturn値のみが帰っているようです。

カテゴリー
C

独習C#第3版、匿名メソッド

using System;

namespace Chapter01All
{
    class Ano
    {
        public int Syukei(int l)
        {
            int w = 0;
            for (int i = 1; i <= l; i++)
            {
                w += i;
            }
            return w;
        }
    }
    class Demo
    {
        static void Main()
        {
            Ano obj = new Ano();
            Console.WriteLine(obj.Syukei(10));
        }
    }
}

class AnoのインスタンスからSyukeiを呼ぶ場合。

using System;

namespace Chapter01All
{
    class Ano
    {
        public static int Syukei(int l)
        {
            int w = 0;
            for (int i = 1; i <= l; i++)
            {
                w += i;
            }
            return w;
        }
    }
    class Demo
    {
        static void Main()
        {
            //Ano obj = new Ano();
            Console.WriteLine(Ano.Syukei(10));
        }
    }
}

Syukeiをstatic に変えると、インスタンスでなくなるので、呼び出す方はAno.Syukei(10)とかになる。

using System;

namespace Chapter01All
{
    delegate int AnoSyukei(int limit);

    class Demo
    {
        static void Main()
        {
            AnoSyukei syukei = delegate (int limit)
            {
                int w = 0;
                for (int i = 1; i <= limit; i++)
                {
                    w += i;
                }
                return w;
            };
            Console.WriteLine(syukei(10));
        }
    }
}

 匿名メソッドに変えてみました。通常のメソッド呼び出し(つまり上の2例のように)の構文によってメソッドを呼び出すことが無い場合、使えるということです。

カテゴリー
C

独習C#第3版、P443 デリゲート、マルチキャスト

// マルチキャストのデモ

using System;
namespace Chapter01All
{
    // デリゲートの宣言
    delegate void StrMod(ref string str);

    class StringOps
    {
        // スペースをハイフンで置き換える
        public void ReplaceSpaces(ref string a)
        {
            Console.WriteLine("Replaces spaces with hyphens.");
            a = a.Replace(' ', '-');
        }
        public void ReplaceHyhoens(ref string a)
        {
            Console.WriteLine("Replaces hyphens with space");
            a = a.Replace('-', ' ');
        }

        // スペースを取り除く
        public void RemoveSpaces(ref string a)
        {
            string temp = "";
            int i;

            Console.WriteLine("Removing spaces.");
            for (i = 0; i < a.Length; i++)
                if (a[i] != ' ') temp += a[i];

            a = temp;
        }

        // 文字列の並びを逆転させる
        public void Reverse(ref string a)
        {
            string temp = "";
            int i, j;

            Console.WriteLine("Reversing string.");
            for (j = 0, i = a.Length - 1; i >= 0; i--, j++)
                temp += a[i];

            a = temp;
        }

        static void Main()
        {
            StringOps obj = new StringOps();
            // デリゲートの作成
            StrMod strOp;
            StrMod replaceSp = obj.ReplaceSpaces;
            StrMod removeSp = obj.RemoveSpaces;
            StrMod reverseStr = obj.Reverse;
            StrMod replacePyhoens = obj.ReplaceHyhoens;

            string str = "This is a test";
            strOp = replaceSp;
            strOp(ref str);
            Console.WriteLine(str + "\n");  //spを-に置き換える

//          strOp -= replaceSp;            
            strOp += reverseStr;
            strOp(ref str);
            Console.WriteLine(str + "\n");  //This-is-a-testを逆文字列にする

            strOp += replacePyhoens;        //再度逆文字列にするので元に戻る。-をspに変える。
            strOp(ref str);
            Console.WriteLine(str + "\n");
/*          以下のコメントアウトは最後以外は本の通りです。
            str = "This is a test.";
            strOp = replaceSp;
            strOp(ref str);
            Console.WriteLine(str + "\n");     //spを-に変える

            // マルチキャストの準備
            strOp = replaceSp;
            strOp += reverseStr; //←マルチキャストを作成する
            // マルチキャストの呼び出し
            str = "This is a test.";
            strOp(ref str);
            Console.WriteLine("Resulting string: " + str);
            Console.WriteLine();    //spaceを-に変えて、逆の文字列にする

            // 置き換えのメソッドを取り除き、スペース削除のメソッドを追加する
            str = "This is a test.";
            strOp = replaceSp;
            strOp += removeSp; //←別のマルチキャストを作成する
            strOp(ref str);
            Console.WriteLine(str + "\n");

            str = "This is a test."; // 文字列を再度設定する

            // マルチキャストの呼び出し
            strOp(ref str);         //文字列を逆にしてから、spを取る
            Console.WriteLine("Resulting string: " + str);
            Console.WriteLine();

            str = "This-is-a-test.";
            strOp = replacePyhoens;
            strOp(ref str);
            Console.WriteLine(str);
*/
        }
    }
}

 本の例題の通り、打ち込んでは見たけれど、少し分かり辛い。実行部分のコメントアウトは、大体本の通り。実行部分の最初を追加しました。例文のスペースをハイフンに変えて、文字列を逆にする。ハイフンをスペースに変えるのを追加して、再度文字列を逆にすると、元に戻る。マルチキャストは加えていくとそのまま残ってますので、スペースを置き換える手順等が残っていても、一度置き換えると、何度行っても何も起こらないことにはなるようです。文字列を逆にするのは、二回行うと元に戻ることになりますね。

inserted by FC2 system